Golang 学习中的疑问,请教一下

2019-08-08 16:30:34 +08:00
 www6688w

Go 的分支语句 “ select ”

我请想请教一下,我该如何通俗的理解这个语句的实际作用和运行原理,官方的说明如下:

“ select 是 Go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作,要么是发送要么是接收。 select 随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行。一个默认的子句应该总是可运行的。

1.每个 case 都必须是一个通信 2.所有 channel 表达式都会被求值 3.所有被发送的表达式都会被求值 4.如果任意某个通信可以进行,它就执行;其他被忽略。 5.如果有多个 case 都可以运行,Select 会随机公平地选出一个执行。其他不会执行。 ”

我自己不能完全的理解的是 “每个 case 都必须是一个通信”

我的疑问如下:

1.以上文中“通信”的定义是什么?也就是在 case 中可以放什么?表达式?还是什么?

2.selcet 分支中 case 是如何进行判断的?

2641 次点击
所在节点    程序员
22 条回复
sulinehk
2019-08-08 16:43:05 +08:00
通信说的是 可以向一个通道取值或发送值

case 就是选择一个执行
poplar50
2019-08-08 16:48:11 +08:00
通俗讲 select 看字面意思就是选择,它会在它的 case 里选择一个来执行,那么问题来了,选择条件是什么? 其实就是哪个 case 准备好了(not blocked)就执行哪个,如果都准备好了就随机选择一个。
SuperMild
2019-08-08 16:50:38 +08:00
tour.golang.org 里面的例子你看看,那些例子很好。
zdt3476
2019-08-08 16:51:53 +08:00
1. 每个 Case 放的都是 channel; 只能放 channel; channel 发送或者是接受语句
2. 就像 你上面第 5 点说的 随机选择一个 case 来执行,比如:
select {
case data := <- ch1: // 可能执行这个
...
case ch2 <- data2: // 也可能执行这个
}
kidlj
2019-08-08 17:08:00 +08:00
读英文。
sirgod
2019-08-08 17:28:57 +08:00
看几个实际的例子就明白了
www6688w
2019-08-08 17:36:01 +08:00
@zdt3476 我现在就是没有完全明白 select 中的 case 要满足什么情况,才算是“可以运行的 case ”。
CRVV
2019-08-08 17:40:00 +08:00
https://golang.org/ref/spec#Channel_types

The capacity, in number of elements, sets the size of the buffer in the channel. If the capacity is zero or absent, the channel is unbuffered and communication succeeds only when both a sender and receiver are ready. Otherwise, the channel is buffered and communication succeeds without blocking if the buffer is not full (sends) or not empty (receives). A nil channel is never ready for communication.

communication succeeds 就是 case 可以运行
gamexg
2019-08-08 17:44:51 +08:00
通信是指的 chan,
表达式最终的返回值必须是 chan。
当然还有个 default。
shingle
2019-08-08 17:45:20 +08:00
一个最常见的例子: 执行一个任务,最多五秒超时, 满足哪个就会触发 select 进行后续的处理
select {
case result := <- ch: // 正常执行,并在 channel 里返回结果

case <- timeout: // 执行超时
}

还有一种, 用于单独开一个协程处理返回结果.
for{
select result := <-ch:
//do something
}
shingle
2019-08-08 17:49:20 +08:00
你给出的是机翻译文吧, 通信一词不应该被翻译...指的是 golang 内置类型 channel
www6688w
2019-08-08 17:55:51 +08:00
@shingle 这个是在一些文章中找到中文的解释,看起来的确不是很容易懂 (°ー°〃)
yangkghjh
2019-08-08 17:58:03 +08:00
类似抢答
SmartKeyerror
2019-08-08 18:15:11 +08:00
不知道是哪里的翻译,但是我觉得用"通道"这个词会更好一些。channel 是通道,目的在于 goroutine 之间的通信。go select 和 Linux select 在语义层面比较相似,都是用于选取已就绪的状态,如果想对 go select 有更深的理解的话,可以看看 Linux select。
panda1001
2019-08-08 18:21:22 +08:00
同意楼上,建议参考 linux select 的原理和使用
OakScript
2019-08-08 18:50:27 +08:00
实在不理解就想成是用于 channel 的 switch,虽然不准确
Pythondr
2019-08-08 19:35:28 +08:00
都放 chan, 哪个 chan 先取到值就执行哪个 case
Y4ssss
2019-08-08 20:02:01 +08:00
哪个通道是没有阻塞的就选择哪个,都没阻塞随机选一个,都阻塞 select 自身阻塞
justfly
2019-08-08 21:35:51 +08:00
你如果了解 linux 内核网络部提供的 select epoll 之类的,理解这个就不难了。
laodao1990
2019-08-09 10:01:40 +08:00
为什么不静下心来了找本书系统的学习下?
推荐 《 Go 语言程序设计》

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/590217

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX