有 select 和只有 select 的 for 循环有什么区别?

whats the difference between for loop with select and only select?

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

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

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

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

谢谢

如果您的程序多次向 'something' 通道发送数据,您将需要重复 select 子句,直到收到完成信号。

例如假设你是运行下面的套路

.... (some calculations)
something <- x 
.... (some calculations)
something <- y
true <- z 

如果您的例程没有 for 循环,它将只接收值 'x' 而不会接收 y 或 z。

带循环的代码将继续打印 来自通道something的数据直到它接收到通道done上的任何数据.

Select-only code will either print data from channel something or 当接收到数据时会退出频道 done 上的任何内容。 只会执行一个案例。请记住,默认情况下,Go selectswitch 语句中没有 fallthrough。

select 语句通过其 cases(sending/receiving 通道)执行一次。如果 none 个案例准备好执行,它将阻塞,直到 case 个案例中至少有一个准备好执行。如果同时有多个case就绪,则随机选择其中一个就绪的case执行。

所以在第二种情况下,如果 something 通道上有一些数据,它将被读取并放入 s。但也有可能 truedone 上发送,而 case s := <-something: 永远不会被执行。

在第一种情况下,您可能想要这样的东西(也是第二种情况):

for{
   select{
   case s := <-something:
       fmt.Println(s)
   case <-done: // note the difference
       return 
   }
}

它现在所做的是等待 something 上的数据,同时也在关注 done。如果something通道上有数据(而done上没有数据),则将其读取并放入s(case分支case s := <-something:将与[=15一起执行=] 具有从 something 读取的值)。这将占 select 语句的一次完整执行,控制将返回到 for 循环并重新开始。

如果 something 通道上没有数据,select 会阻塞并等待 somethingdone 上的数据。如果数据到达 something,将执行与上述类似的操作,否则如果数据到达 done,函数 returns(跳出循环)。这样一些其他进程可以写入 done 并向包含上述 for 循环的函数发出信号以停止处理 something 和 return.