在Go程序中你会一遍又一遍地看到for-select循环: ``` for { // 无限循环或遍历 select { // 对通道进行操作 } } ``` 比较常见的有以下几种不同的情况: ***在通道上发送迭代变量*** 通常情况下,你需要将可迭代的内容转换为通道上的值。 ``` for _, s := range []string{"a", "b", "c"} { select { case <-done: return case stringStream <- s: } } ``` ***无限循环等待停止*** 创建无限循环直到停止的例子很常见。这有一些变化。 你选择哪一个纯粹是一种偏好。 第一种变体保持select语句尽可能短: ``` for { select { case <-done: return default: } // 执行非抢占任务 } ``` 如果done通道没有关闭,我们会退出select语句并执行循环体剩下的部分。 第二种变体将任务嵌入到select语句的默认子句中: ``` for { select { case <-done: return default: // 执行非抢占任务 } } ``` 当我们进入select语句时,如果done通道尚未关闭,我们将执行default子句。 这种模式没有什么高深的地方,但它展示了最常见的使用方式,所以值得一提。 * * * * * 学识浅薄,错误在所难免。我是长风,欢迎来Golang中国的群(211938256)就本书提出修改意见。