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
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
vue实现excel表格的导入导出的示例
模型训练时GPU利用率太低的原因及解决
python中opencv实现图片文本倾斜校正
![](https://img.aspxhome.com/file/2023/5/109385_0s.jpg)
Python中Dict两种实现的原理详解
Golang 限流器的使用和实现示例
SQL Server的触发器你了解多少
详解Pycharm出现out of memory的终极解决方法
![](https://img.aspxhome.com/file/2023/0/112780_0s.png)
Golang如何交叉编译各个平台的二进制文件详解
![](https://img.aspxhome.com/file/2023/6/125086_0s.png)
详细解析Python当中的数据类型和变量
![](https://img.aspxhome.com/file/2023/2/86582_0s.png)
踩坑:pytorch中eval模式下结果远差于train模式介绍
opencv3/C++图像像素操作详解
![](https://img.aspxhome.com/file/2023/1/105061_0s.jpg)
如何利用Python随机从list中挑选一个元素
Python标准模块--ContextManager上下文管理器的具体用法
Pycharm操作Git及GitHub的步骤详解
![](https://img.aspxhome.com/file/2023/1/83651_0s.png)
Vue3 组件库的环境配置搭建过程
![](https://img.aspxhome.com/file/2023/6/130286_0s.png)
python使用pandas按照行数分割表格
![](https://img.aspxhome.com/file/2023/5/72045_0s.jpg)
实例讲解Python脚本成为Windows中运行的exe文件
Yii配置文件用法详解
如何用ASP实现文章点击数?
Python实现爆破ZIP文件(支持纯数字,数字+字母,密码本)
![](https://img.aspxhome.com/file/2023/5/135245_0s.png)