无法从文档或谷歌中完全理解它:
两者之间有什么区别 你会使用哪种情况?
for{
select{
case s := <-something:
fmt.Println(s)
case done := <-true:
return
}
}
和
select{
case s := <-something:
fmt.Println(s)
case done := <-true:
return
}
由于
答案 0 :(得分:9)
代码循环将保持打印数据来自频道something
,直到它在频道done
上收到任何内容。
仅选择代码将 打印来自频道something
或的数据,当它在频道done
上收到任何内容时将退出。 只会执行一个案例。请注意,默认情况下,Go select
和switch
语句没有任何影响。
答案 1 :(得分:1)
如果您的程序多次向'某些'通道发送数据,您将需要重复select子句,直到收到完成信号。
例如,假设您正在运行以下例程
.... (some calculations)
something <- x
.... (some calculations)
something <- y
true <- z
如果你的例程没有for循环,它只会收到值'x'并且不会收到y或z。
答案 2 :(得分:1)
select
语句通过其cases
(发送/接收频道)执行一次。如果它的所有情况都没有准备好执行,它将一直阻塞,直到case
中至少有一个准备好执行。如果同时准备好多个案例,则选择其中一个就绪案例随机执行。
因此,在第二种情况下,如果something
频道上有一些数据,则会将其读取并放入s
。但true
也有可能done
发送,而case s := <-something:
永远不会被执行。
在第一种情况下,你可能想要这样的东西(在第二种情况下):
for{
select{
case s := <-something:
fmt.Println(s)
case <-done: // note the difference
return
}
}
现在的做法是等待something
上的数据,同时关注done
。如果something
频道上有数据(且done
上没有数据),则会将其读取并放入s
(案例分支case s := <-something:
将以{{1}执行具有从s
读取的值。这将占something
语句的一次完整执行,控件将返回select
循环,它将重新开始。
如果for
频道上没有数据,something
会屏蔽并等待select
或something
上的数据。如果数据到达done
,则会发生与上面类似的执行,否则如果它到达something
,则函数返回(中断循环)。这样,其他一些进程可以写入done
并发出包含上述done
循环的函数的信号,以停止处理for
并返回。