Goでchannelがcloseしてるかどうか知りたい というアンチパターン - beatsync.net
そもそもGoのchannelがcloseしてるかどうかを知りたいっていう理由は、だいたい「Goのchannelはナイーブだから」というところに起因するのはないかと思います。
https://beatsync.net/main/log20150325.html
golang には元々 closed()
という、channel が閉じられているかどうかを返す組み込み関数がありました。しかし廃止されました。
closed は API としては目的を達成出来ているのですが、builtin が1つ増える、channel から取り出す前に一度確認する必要があるという理由で削除されたと私は記憶しています。
Goでchannelがcloseしてるかどうか知りたい というアンチパターン - beatsync.net
selectをつかってブロックする可能性のある文をcaseにかけば一番最初にブロックが外れたやつに分岐します。で、これは@fujiwaraさんに教えてもらった技ですが、なんもしないdefaultを書けばブロックせずにすぐdefaultにおちるとのこと。
https://beatsync.net/main/log20150325.html
実際には closed()
が無くなった訳ではなく、型アサーションと同じインタフェースに置き換えられました。
Issue 4243072: code review 4243072: go code: replace closed(c) with x, ok := <-c - Code Review
LGTM http://codereview.appspot.com/4243072/diff/5001/src/pkg/os/inotify/inotify_li... File src/pkg/o...
https://codereview.appspot.com/4243072/
x, ok := <-c
戻り値の2つ目に channel から取り出せたかどうかが bool で返ります。
select はどちらかと言うと、複数の channel を同時に待てる仕組みであり、閉じている channel の case には飛ばないという理由で動いています。ですのでどうしても select は嫌だという方は以下の様に書くと良いです。(注意: ブロックはするので select とは動作が違う事に注意)
if x, ok := <-c; ok {
// x を使った処理
}