web-dev-qa-db-fra.com

Comment tester si un canal est fermé et ne l'envoyer que lorsqu'il n'est pas fermé

Dans Go, si un canal channel est fermé, je peux toujours le lire en utilisant la syntaxe suivante et je peux tester ok pour voir s'il est fermé.

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

Cependant, si je ne sais pas si un canal est fermé et que j'écris aveuglément dessus, je peux avoir une erreur. Je veux savoir s'il existe un moyen de tester la chaîne et de ne l'écrire que lorsqu'elle n'est pas fermée. Je pose cette question parce que parfois je ne sais pas si un canal est fermé ou non dans un goroutine.

16
Just a learner

Tu ne peux pas. La règle générale ici est que seuls les auteurs doivent fermer les chaînes, de cette façon, vous savez que vous ne devriez plus écrire sur cette chaîne.

Un code simple ressemblerait à ceci:

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

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

Si quelques goroutins écrivent sur le canal, vous pouvez également nil au lieu de close et utiliser select pour lire et écrire. Quelque chose comme ça

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")
}

Essayez que cela fonctionne https://play.golang.org/p/sp8jk961TB

5
Uvelichitel