Go for-select循环

For-Select

在 Go 程序中你会一遍又一遍地看到 for-select 循环:

1
2
3
4
5
for { // 无限循环或遍历
select {
// 对通道进行操作
}
}

比较常见的有以下几种不同的情况:

在通道上发送迭代变量
通常情况下,你需要将可迭代的内容转换为通道上的值。

1
2
3
4
5
6
7
for _, s := range []string{"a", "b", "c"} {
select {
case <-done:
return
case stringStream <- s:
}
}

无限循环等待停止
创建无限循环直到停止的例子很常见。这有一些变化。 你选择哪一个纯粹是一种偏好。

第一种变体保持 select 语句尽可能短:

1
2
3
4
5
6
7
8
9
10
for {
select {
case <-done:
return
default:
}

// 执行非抢占任务

}

如果 done 通道没有关闭,我们会退出 select 语句并执行循环体剩下的部分。

第二种变体将任务嵌入到 select 语句的默认子句中:

1
2
3
4
5
6
7
8
for {
select {
case <-done:
return
default:
// 执行非抢占任务
}
}

当我们进入 select 语句时,如果 done 通道尚未关闭,我们将执行 default 子句。

这种模式没有什么高深的地方,但它展示了最常见的使用方式,所以值得一提。