web-dev-qa-db-ja.com

チャネルが閉じているかどうかをテストし、閉じていないときにのみ送信する方法

Goでは、チャネルchannelが閉じている場合でも、次の構文を使用して読み取りができ、okをテストして、閉じているかどうかを確認できます。

value, ok := <- channel
if !ok {
    // channel was closed and drained
}

ただし、チャネルが閉じているかどうかわからず、盲目的に書き込みを行うと、エラーが発生する場合があります。チャンネルをテストし、閉じられていないときにのみ書き込むことができる方法があるかどうかを知りたいです。この質問は、ゴルーチンでチャンネルが閉じているかどうか分からないことがあるためです。

16
Just a learner

できません。ここでの経験則は、作家のみがチャネルを閉じるべきであるということです。この方法では、そのチャネルにこれ以上書き込むべきではないことがわかります。

いくつかの簡単なコードは次のようになります。

for i := 0; i < 100; i++ {
    value := calculateSomeValue()
    channel <- value
}

close(channel) //indicate that we will no more send values
17
serejja

少数のgoroutinがチャネルに書き込む場合、nilの代わりにcloseを使用し、selectを使用して読み書きすることもできます。このようなもの

ch := make(chan int, 1)
var value int
ch <- 5
select {
case value = <-ch:
    fmt.Println("value", value)
default:
    fmt.Println("oops")
}
ch = nil
select {
case ch <- 5:
default:
    fmt.Println("don't panic")
}
select {
case value = <-ch:
    fmt.Println("value", value)
default:
    fmt.Println("oops")
}

試してみてください https://play.golang.org/p/sp8jk961TB

5
Uvelichitel