Middle
Welke gevolgen kunnen er optreden bij het lezen uit een gesloten kanaal in Go?
sobes.tech AI
Antwoord van AI
Het lezen uit een gesloten kanaal geeft onmiddellijk de null-waarde van het elementtype van het kanaal zonder blokkering. Als er een tweede booleaanse parameter wordt geretourneerd, is deze false.
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 1) // Gecapteerde kanaal
ch <- 1
close(ch)
val, ok := <-ch // Lezen uit een gesloten kanaal
fmt.Printf("Waarde: %d, Open: %t\n", val, ok) // Zal "Waarde: 1, Open: true" afdrukken
val, ok = <-ch // Herhaald lezen uit hetzelfde gesloten kanaal
fmt.Printf("Waarde: %d, Open: %t\n", val, ok) // Zal "Waarde: 0, Open: false" afdrukken
// Verdere lezingen uit het gesloten kanaal
val, ok = <-ch
fmt.Printf("Waarde: %d, Open: %t\n", val, ok) // Zal "Waarde: 0, Open: false" afdrukken
}
Belangrijkste gevolgen:
- Null-waarde verkrijgen: Het programma zal niet crashen, maar krijgt de standaard null-waarde voor het kanaaltype.
- Sluitingsindicator: De tweede booleaanse parameter, indien gebruikt, wordt
false, wat aangeeft dat het kanaal gesloten is en de verkregen waarde null is. - Niet-blokkerende lezing: De lezing zal de goroutine niet blokkeren.
- Geen panic: In tegenstelling tot schrijven naar een gesloten kanaal, veroorzaakt lezen uit een gesloten kanaal geen panic.
Vergelijking van lezen uit open en gesloten kanalen:
| Kanaalstatus | Operatie | Gedrag | Geretourneerde waarde (indien tweede parameter aanwezig) |
|---|---|---|---|
| Open | <-ch |
Blokkeert tot waarde of sluiting wordt ontvangen | Waarde, true |
| Open | val, ok := <-ch |
Blokkeert tot waarde of sluiting wordt ontvangen | Waarde, true |
| Gesloten | <-ch |
Onmiddellijk ontvangen | Null-waarde |
| Gesloten | val, ok := <-ch |
Onmiddellijk ontvangen | Null-waarde, false |
Het gebruik van de tweede booleaanse parameter wordt aanbevolen om te bepalen of een echt element uit het kanaal is ontvangen of dat het kanaal gesloten is.
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 1)
ch <- 1
close(ch)
for {
val, ok := <-ch
if !ok {
fmt.Println("Kanaal is gesloten, einde van de lus.")
break
}
fmt.Printf("Ontvangen waarde: %d\n", val)
}
}
Dit gedrag maakt het mogelijk om goroutines die uit het kanaal lezen elegant te beëindigen na sluiting.