Channel
Un channel è una struttura del Go per permettere a routine diverse di comunicare tra loro.
Un channel è una risorsa in memoria dinamica e pertanto va allocato con la funzione make
.
Un channel ha un tipo dei dati che può trasmettere.
La lettura e scrittura avvengono con l'operatore <-
, da vedersi come una freccia indicante la direzione di flusso dei dati.
Esempio
(230channels.go):
package main
import "fmt"
func main() {
// Un channel è una primitiva di connessione fra goroutines
messages := make(chan string)
// Invio di un messaggio al channel
go func() { messages <- "ping" }()
// Recupero di un messaggio dal channel
msg := <-messages
fmt.Println(msg)
}
La lettura da un channel è bloccante. La routine non può proseguire finchè non vi sono dati da legger dal channel, ciè finchè un'altra routine non scriva qualcosa nel channel.
Questo è il fondamento del meccanismo di sincronizzazione.
Channel non inizializzato
(232-uninitialized-channel.go):
package main
import "fmt"
// I Channel devono essere inizializzati con make
// Un channel globale non inizializzato
var str chan string
// Sostituirlo col seguente per farlo funzionare
// var str = make(chan string)
func main() {
// Goroutine invia un messaggio al channel
go func() {
str <- "hello"
}()
// Recupero di un messaggio dal channel
msg := <-str
fmt.Println(msg)
}
// Un channel non inizializzato vale 'nil'
// Regole:
// 1. receive da channel nil si blocca
// 2. send a channel nil si blocca
// 3. send a un canale chiuso va in panic
// 4. receive da un canale chiuso ritorna uno zero
Regole
Un channel non inizializzato vale 'nil'. Regole:
- receive da channel nil si blocca
- send a channel nil si blocca
- send a un channel chiuso va in panic
- receive da un channel chiuso ritorna uno zero
Occorre compiere molta attenzione ad inizializzare sempre i channel.