Ce face close
close(c) marchează canalul ca închis. Valorile deja aflate în buffer se pot citi în continuare; după ce buffer-ul se golește, orice primire returnează imediat valoarea zero a tipului, iar în forma v, ok := <-c, ok este false. Bucla for v := range c se oprește singură.
Doar expeditorul ar trebui să închidă canalul, o singură dată, când a terminat de trimis. Închiderea nu este obligatorie: un canal neînchis este eliberat oricum de colectorul de memorie. Se închide doar când destinatarul trebuie să afle că nu mai vin date. Un canal închis este și un semnal pentru mai multe goroutine deodată: toate cele care așteaptă pe <-c se deblochează.
Parametri
| Parametru | Descriere |
|---|---|
c |
Un canal bidirecțional sau doar pentru trimitere (chan<- T). |
Exemple
Exemplul 1: Valorile din buffer rămân disponibile
package main
import "fmt"
func main() {
c := make(chan int, 3)
c <- 10
c <- 20
close(c)
v, ok := <-c
fmt.Println(v, ok)
v, ok = <-c
fmt.Println(v, ok)
v, ok = <-c // buffer gol și canal închis
fmt.Println(v, ok)
}
Rezultat
10 true
20 true
0 false
Exemplul 2: Semnal de oprire pentru mai multe goroutine
close(stop) deblochează toți lucrătorii deodată; fiecare raportează în propria poziție, iar afișarea este în ordine.
package main
import (
"fmt"
"sync"
)
func main() {
stop := make(chan struct{})
stari := make([]string, 3)
var wg sync.WaitGroup
for i := range 3 {
wg.Add(1)
go func() {
defer wg.Done()
<-stop // așteaptă semnalul
stari[i] = fmt.Sprintf("lucrătorul %d s-a oprit", i+1)
}()
}
close(stop)
wg.Wait()
for _, s := range stari {
fmt.Println(s)
}
}
Rezultat
lucrătorul 1 s-a oprit
lucrătorul 2 s-a oprit
lucrătorul 3 s-a oprit
Greșeli frecvente
- Trimitere după
close:panic: send on closed channel. - Închiderea de două ori:
panic: close of closed channel. closepe un canalnil:panic: close of nil channel.- Închiderea unui canal doar pentru primire (
<-chan T):invalid operation: cannot close receive-only channel.
Comenzi înrudite
chan și canale (channels): Canalele (chan) transmit valori între goroutine în siguranță și le sincronizează; se creează cu make.select: Așteaptă mai multe operații pe canale deodată și o execută pe prima care este gata; cu default nu blochează.go și goroutine: Cuvântul go pornește o funcție într-o goroutine: un fir de execuție ușor, care rulează în paralel cu restul programului.range: Parcurge într-un for elementele unui slice, array, map, text, canal, număr sau iterator.