English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In linguaggio Go, i canali sono il mezzo di comunicazione tra goroutine e altri goroutine, e questa comunicazione è senza lock. In altre parole, un canale è una tecnica che permette a una goroutine di inviare dati a un'altra goroutine. Di default, i canali sono bidirezionali, il che significa che le goroutine possono inviare o ricevere dati attraverso lo stesso canale, come mostrato nella figura seguente:
In Go, viene utilizzata la parola chiave chan per creare un canale, e il canale può trasmettere solo dati dello stesso tipo, non è permesso trasmettere dati di tipo diverso attraverso lo stesso canale.
Sintassi:
var Channel_name chan Type
Puoi anche utilizzare la dichiarazione abbreviata attraverso la funzione make().
Sintassi:
channel_name:= make(chan Type)
package main import "fmt" func main() { //Utilizzare la parola chiave var per creare un canale var mychannel chan int fmt.Println("Il valore di channel: ", mychannel) fmt.Printf("Il tipo di channel: %T ", mychannel) // Utilizzare la funzione make() per creare un canale mychannel1 := make(chan int) fmt.Println("\nIl valore di channel1:", mychannel1) fmt.Printf("Il tipo di channel1: %T ", mychannel1) }
Output:
Il valore di channel: <nil> Il tipo di channel: chan int Il valore di channel1: 0xc0000160c0 Il tipo di channel1: chan int
In Go, il funzionamento dei canali ha due operazioni principali, una è l'invio e l'altra è la ricezione, queste due operazioni sono denominate comunemente comunicazione. La direzione dell'operatore <- indica se si sta ricevendo dati o inviando dati. Di default, nell'ambito del canale, le operazioni di invio e ricezione bloccano fino a quando l'altro estremo non ha più dati. Questo permette alle goroutine di sincronizzarsi tra loro senza la necessità di lock espliciti o variabili di condizione.
Operazione di invio:L'operazione di invio viene utilizzata per inviare dati da una goroutine all'altra con l'aiuto di un canale. Valori come int, float64 e bool possono essere inviati in modo sicuro e facile attraverso il canale perché vengono copiati, quindi non c'è rischio di accesso concorrente non previsto allo stesso valore. Allo stesso modo, le stringhe sono sicure perché sono immutabili. Tuttavia, non è sicuro inviare tramite canale puntatori o riferimenti (ad esempio, tagli, insiemi di mappe, ecc.) perché i valori dei puntatori o dei riferimenti possono essere modificati contemporaneamente da una goroutine di invio o di ricezione, e i risultati sono imprevedibili. Pertanto, quando si utilizzano puntatori o riferimenti nei canali, è necessario assicurarsi che possano essere acceduti da una sola goroutine alla volta.
Mychannel <- element
La frase sopra indica che i dati (element) sono stati<-l'aiuto dell'operatore viene inviato al canale (Mychannel).
operazione di ricezione:L'operazione di ricezione viene utilizzata per ricevere i dati inviati dal mittente dell'operazione di invio.
element := <-Mychannel
La frase sopra indica che l'elemento viene ricevuto dal canale (Mychannel). Se la frase ricevuta non è disponibile (non necessaria), è anche una frase valida. Puoi anche scrivere una frase di ricezione come segue:
<-Mychannel
package main import "fmt" func myfunc(ch chan int) { fmt.Println(234 + <-ch) } func main() { fmt.Println("metodo principale inizia") //creazione del canale l ch := make(chan int) go myfunc(ch) ch <- 23 fmt.Println("metodo principale finisce") }
Output:
metodo principale inizia 257 metodo principale finisce
Puoi anche chiudere il canale con l'aiuto della funzione close(). È una funzione integrata che imposta un indicatore che non ci saranno più valori inviati al canale.
Sintassi:
close()
Puoi anche utilizzare un ciclo for range per chiudere il canale. In questo caso, il goroutine ricevitore può utilizzare la sintassi fornita per verificare se il canale è aperto o chiuso:
ele, ok := <-Mychannel
In questo caso, se il valore di ok è true, significa che il canale è aperto e quindi è possibile eseguire operazioni di lettura. E se il valore è false, significa che il canale è chiuso, quindi non verrà eseguita alcuna operazione di lettura.
//Spiega come il programma Go //chiusura del canale utilizzato //ciclo range e funzione di chiusura package main import "fmt" func myfun(mychnl chan string) { for v := 0; v < 4; v++ { mychnl <- "w3codebox" } close(mychnl) } func main() { //creazione del canale c := make(chan string) //utilizzo di Goroutine go myfun(c) //quando il valore di ok è impostato su true, significa che il canale è aperto e può inviare o ricevere dati //quando il valore di ok è impostato su false, significa che il canale è stato chiuso for { res, ok := <-c if ok == false { fmt.Println("canale chiuso", ok) ferma } fmt.Println("Apertura del canale: ", res, ok) } }
Output:
Apertura del canale: w3codebox true Apertura del canale: w3codebox true Apertura del canale: w3codebox true Apertura del canale: w3codebox true Chiusura del canale: false
Blocco di invio e ricezione:Nel canale, quando i dati vengono inviati al canale, il controllo viene bloccato nella frase di invio fino a quando un altro goroutine non legge i dati dal canale. Allo stesso modo, quando il canale riceve dati da un goroutine, la frase di lettura viene bloccata fino a quando un altro goroutine non esegue una frase di scrittura.
Canale con valore zero: Il canaleIl valore zero è nil.
Ciclo for nel canale: Il ciclo for può esplorare i valori in ordine di invio sul canale fino a quando non viene chiuso.
Sintassi:
for item := range Chnl { // Statements... }
package main import "fmt" func main() { // Utilizzare la funzione make() per creare un canale mychnl := make(chan string) // Goroutine anonima go func() { mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox" close(mychnl) } // Utilizzare il ciclo for for res := range mychnl { fmt.Println(res) } }
Output:
GFG gfg Geeks w3codebox
La lunghezza del canale:Nel canale, è possibile utilizzareFunzione len()Trovare la lunghezza del canale. In questo caso, la lunghezza rappresenta il numero di valori in attesa nel buffer del canale.
package main import "fmt" func main() { // Utilizzare la funzione make() per creare un canale mychnl := make(chan string, 4) mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox" // Utilizzare la funzione len() per trovare la lunghezza del canale fmt.Println("La lunghezza del canale è: ", len(mychnl)) }
Output:
La lunghezza del canale è: 4
Capacità del canale:Nel canale, è possibile utilizzare la funzione cap() per trovare la capacità del canale. In questo caso, la capacità rappresenta la dimensione del buffer.
package main import "fmt" func main() { // Utilizzare la funzione make() per creare un canale mychnl := make(chan string, 4) mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox" // Utilizzare la funzione cap() per trovare la capacità del canale fmt.Println("La capacità del canale è: ", cap(mychnl)) }
Output:
La capacità del canale è: 5
Select e frasi case nel canale:Nel linguaggio Go, la frase select è come una frase switch senza parametri di input. Utilizzare la frase select per eseguire un'operazione singola tra più operazioni fornite dai blocchi case del canale.