什么是for循环与select和仅选择之间的区别?

时间:2016-07-12 15:25:24

标签: go goroutine

无法从文档或谷歌中完全理解它:

两者之间有什么区别 你会使用哪种情况?

    for{
       select{
       case s := <-something:
           fmt.Println(s)
       case done := <-true:
           return 
       }
    }

       select{
       case s := <-something:
           fmt.Println(s)
       case done := <-true:
           return 
       }

由于

3 个答案:

答案 0 :(得分:9)

代码循环将保持打印数据来自频道something ,直到它在频道done上收到任何内容。

仅选择代码将 打印来自频道something 的数据,当它在频道done上收到任何内容时将退出。 只会执行一个案例。请注意,默认情况下,Go selectswitch语句没有任何影响。

答案 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会屏蔽并等待selectsomething上的数据。如果数据到达done,则会发生与上面类似的执行,否则如果它到达something,则函数返回(中断循环)。这样,其他一些进程可以写入done并发出包含上述done循环的函数的信号,以停止处理for并返回。