Go语言面试题之select和channel的用法
作者:王中阳Go 发布时间:2024-04-26 17:27:39
select
先说switch...case...
switch...case... 很常用,且很好理解。其作用和if...else...一样。
区别是switch...case 相比于if...else...能让我们的代码看起来更清晰,更好理解。
再说select...case..
golang 的 select 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。
所说的IO操作就是对channle的操作:向通道发送数据,或者从通道中读取数据。
在执行select语句的时候,运行时系统会自上而下地判断每个case中的发送或接收操作是否可以被立即执行。
什么是立即执行呢?
立即执行:意思是当前Goroutine不会因当前操作而被阻塞
select类比switch
select的用法与switch非常类似,由select开始一个新的选择块,每个选择条件由case语句来描述。
与switch语句可以选择任何可使用相等比较的条件相比,select有比较多的限制,其中最大的一条限制就是每个case语句里必须是一个IO操作。
确切的说,应该是一个面向channel的IO操作。
经典示例
package main
import "fmt"
func main() {
ch1 := make(chan int, 1)
ch1 <- 2
select {
case v := <-ch1:
fmt.Println("取到的数据:", v)
case ch1 <- 1:
fmt.Println("写入数据")
}
}
运行结果
channel
goroutine和channel作为go语言中最重要的两个知识点,一定要搞清楚。
大家容易出错的知识点是以下3点,尤其是最后一点:
1.nil channel代表channel未初始化,向未初始化的channel读写数据会造成阻塞
2.关闭(close)未初始化的channel会引起panic。
3.从一个关闭的并且没有值的通道执行接收操作会得到对应类型的零值,并不会引起panic。
1.从已经关闭并且没有值的通道中取值
package main
import "fmt"
//从关闭的通道中取值示例:
func main() {
//声明实例化通道ch1
ch1 := make(chan int, 1)
//关闭通道
close(ch1)
select {
//通通道ch1中取值
case v := <-ch1:
fmt.Printf("从ch1中取值:%d\n", v)
default:
fmt.Println("默认case")
}
}
运行结果
和我们预想中的一样,取到了对应的零值:
2.从已经关闭并且有值的通道中取值
我们稍微修改一下上面的代码
package main
import "fmt"
//从关闭的通道中取值示例:
func main() {
//声明实例化通道ch1
ch1 := make(chan int, 1)
//向通道中赋值
ch1 <- 1
//关闭通道
close(ch1)
//关闭之后取值
after_close_value := <-ch1
fmt.Printf("关闭之后取值:%d\n", after_close_value) //打印结果:关闭之后取值:1
select {
//通通道ch1中取值
case v := <-ch1:
fmt.Printf("从ch1中取值:%d\n", v) //打印结果:从ch1中取值:0
default:
fmt.Println("默认case")
}
}
运行结果
运行结果和我们预想中的一样:
通道关闭后,如果通道中仍然有值,还是可以正常取到通道中的值的。
通道关闭后,如果通道中已经没有值了,再从通道中取值,并不会引起panic,而是会取到对应类型的零值。
一图胜千言
下面的表格中总结了对不同状态下的通道执行相应操作的结果。
注意: 对已经关闭的通道再执行 close 也会引发 panic。
来源:https://juejin.cn/post/7139768397423706126
猜你喜欢
- SQL Server的作业调度来建立自动备份的方法◆1、进入企业管理器中->管理->sql server代理->作业;◆2
- 以前在使用Python的时候,都是使用root用户安装好的全局python,现在,因为root用户安装的Python版本太低,同时自己没有r
- 文章主要讲术了一些SQL Server新的Bug,帮您认识这些被忽略的SQL Server注入技巧。1.关于Openrowset和Opend
- 我就废话不多说,直接上代码吧!# -*- coding: utf-8 -*-import cv2import numpy as npfrom
- 级联查询在ORACLE 数据库中有一种方法可以实现级联查询select * //要查询的字段from table
- 此方法支持IE 不支持火狐。可能是因为FCKEidtor的keyup方法在火狐下不被支持。 FCKEditor编辑器换为TextBox,应该
- 日常在网站使用过程中经常遇到图形验证,今天准备自己做个图形验证码,这算是个简单的功能,也适合新手练习的,便于自己学习。 主要用到的库--PI
- 注:所谓n位数“水仙花数”是指一个n数,其各位数字n次方和等于该数本身。如三位数“水仙花数”是指一个三位数,其各位数3次方和等于该数本身。一
- 保存模型保存模型仅仅是为了测试的时候,只需要torch.save(model.state_dict, path)path 为保存的路径但是有
- 执行以下SQL,即OK咯叻!! SQL:alter database 数据库名称 SQL_Latin1_General_CP1_CI_AS
- 直接贴代码import subprocessdef get_system_stats(): # 通过 shell
- 一 计算公式:二 实现代码(1)import mathfrom tqdm import tqdmimport timetotal,s,n,t
- 这篇文章主要介绍了python3获取文件中url内容并下载代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价
- MYSQL TIMESTAMP字段进行时间加减运算在数据分析过程中,想当然地对TIMESTAMP字段进行运算,导致结果谬之千里计算公式如下-
- 本文实例讲述了python中sys.argv参数用法。分享给大家供大家参考。具体分析如下:在学python的过程中,一直弄不明白sys.ar
- 数据库账号密码加密详解及实例数据库中经常有对数据库账号密码的加密,但是碰到一个问题,在使用UserService对密码进行加密的时候,spr
- 类、构造函数、原型先来说明一点:在上面的内容中提到,每一个函数都包含了一个prototype属性,这个属性指向了一个prototype对象(
- 如下所示:import pymysqlimport timeimport redef get_raw_label(rece): re1 =
- 目标:文件的概念文件的基本操作文件/文件夹的常用操作文本文件的编码方式1.文件的概念1.1文件的概念和作用计算机的文件,就是存储在某种长期存
- 如下所示:<strong><span style="font-size:14px;">文本过滤&