Как проверить, если канал закрыт и отправлять на него, только если он не закрыт

В Go, если канал channel закрыт, я все еще могу читать с него, используя следующий синтаксис, и я могу проверить, ok ли он закрыт.

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

Однако, если я не знаю, закрыт ли канал и пишу ему вслепую, я могу получить ошибку. Я хочу знать, есть ли способ проверить канал и писать на него, только когда он не закрыт. Я задаю этот вопрос потому, что иногда я не знаю, закрыт канал или нет в программе.

Ответ 1

Вы не можете. Основное правило здесь заключается в том, что только писатели должны закрывать каналы, так что вы знаете, что больше не следует писать на этот канал.

Простой код будет выглядеть так:

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

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

Ответ 2

Если несколько каналов пишут на канал, вы можете также 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