Chiudere Channel
#
// Chiudere un channel serve ad indicare che non verranno
// più inviati su quel channel.
// Questo è utile per comunicare il completamento di
// un operazione a chi sta ascoltando sul channel.
package main
import "fmt"
// In questo esempio useremo un channel `jobs` per
// inviare i task che devono essere eseguiti dalla
// goroutine `main()` a una goroutine che svolge il
// ruolo di `worker`. Quando non si hanno più task
// da eseguire si chiuderà il channel `jobs` tramite
// il built-in `close`.
func main() {
jobs := make(chan int, 5)
done := make(chan bool)
// Questa è la goroutine worker, che riceverà i task
// in modo continuativo dal channel `jobs` tramite il
// comando `j, more := <-jobs`. Utilizzando questa forma
// speciale per ricevere i valori, nella variabile
// `more` avremo il valore `false` se il channel `jobs`
// è stato chiuso e tutti i valori sono stati ricevuti.
// Utilizzeremo questo valore per indicare quando la
// goroutine ha terminato di eseguire tutti i task che
// ha ricevuto.
go func() {
for {
j, more := <-jobs
if more {
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()
// Questo invia 3 job alla goroutine worker sul channel
// `jobs` e lo chiude subito dopo.
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job", j)
}
close(jobs)
fmt.Println("sent all jobs")
// Attendiamo la goroutine worker utilizzando l'approccio
// di [sincronizzazione](sincronizzazione-dei-channel) che abbiamo
// visto negli esempi precedenti
<-done
}
$ go run closing-channels.go
sent job 1
received job 1
sent job 2
received job 2
sent job 3
received job 3
sent all jobs
received all jobs
# L'esempio che segue deriva direttamente dal concetto di
# chiusura di un channel: come effettuare un `range`
# su un channel.