私は2つのゴルーチンが独立してデータを生成し、それぞれがデータをチャネルに送信しています。私のメインのゴルーチンでは、これらの各出力を入力時に消費したいと思いますが、入力の順序は気にしないでください。各チャネルは、出力がなくなると自動的に閉じます。selectステートメントは、このように独立して入力を消費するための最も優れた構文ですが、両方のチャネルが閉じるまで、それぞれをループする簡潔な方法を見たことがありません。
for {
select {
case p, ok := <-mins:
if ok {
fmt.Println("Min:", p) //consume output
}
case p, ok := <-maxs:
if ok {
fmt.Println("Max:", p) //consume output
}
//default: //can't guarantee this won't happen while channels are open
// break //ideally I would leave the infinite loop
//only when both channels are done
}
}
私が考えることができる最善のことは次のとおりです(スケッチしたばかりで、コンパイルエラーがある可能性があります):
for {
minDone, maxDone := false, false
select {
case p, ok := <-mins:
if ok {
fmt.Println("Min:", p) //consume output
} else {
minDone = true
}
case p, ok := <-maxs:
if ok {
fmt.Println("Max:", p) //consume output
} else {
maxDone = true
}
}
if (minDone && maxDone) {break}
}
しかし、これは、2つまたは3つを超えるチャネルで作業している場合は受け入れられないように見えます。私が知っている他の唯一の方法は、switchステートメントでtimoutケースを使用することです。これは、早期に終了するリスクを冒すのに十分小さいか、最終ループに過度のダウンタイムを注入します。selectステートメント内にあるチャネルをテストするためのより良い方法はありますか?