English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
No Go language, channels are the medium for communication between goroutines, and this communication is lock-free. In other words, a channel is a technology that allows one goroutine to send data to another goroutine. By default, channels are bidirectional, which means goroutines can send or receive data through the same channel, as shown in the following figure:
No idioma Go, usar a palavra-chave chan para criar canais, e esses canais podem transmitir apenas dados do mesmo tipo, não permitindo que dados de diferentes tipos sejam transmitidos pelo mesmo canal.
Sintaxe:
var Channel_name chan Type
Você também pode usar declarações abreviadas para criar canais através da função make().
Sintaxe:
channel_name:= make(chan Type)
package main import "fmt" func main() { //Usar a palavra-chave var para criar um canal var mychannel chan int fmt.Println("o valor do canal: ", mychannel) fmt.Printf("o tipo do canal: %T ", mychannel) // Usar a função make() para criar um canal mychannel1 := make(chan int) fmt.Println("\ncanal1o valor:1) fmt.Printf("canal1o tipo: %T "1) }
Saída:
o valor do canal: <nil> o tipo do canal: chan int canal1o valor: 0xc0000160c0 canal1do tipo: chan int
No idioma Go, o trabalho com canais tem duas operações principais: uma é o envio e a outra é a recebimento, essas duas operações são coletivamente chamadas de comunicação.-A direção do operador indica se é para receber ou enviar dados. No canal, por padrão, as operações de envio e recebimento bloqueiam até que o outro extremo não tenha mais dados. Isso permite que as goroutines se sincronizem umas com as outras sem locks explícitos ou variáveis de condição.
Operação de envio:As operações de envio são usadas para enviar dados de uma goroutine para outra através de canais. Como int, float64Os valores como bool e outros podem ser enviados com segurança e facilidade através de canais, pois são copiados, portanto, não há risco de acesso concorrente acidental ao mesmo valor. Da mesma forma, as strings são seguras, pois são imutáveis. No entanto, enviar ponteiros ou referências (por exemplo, fatias, conjuntos map) através de canais não é seguro, pois os valores desses ponteiros ou referências podem ser alterados por goroutines que enviam ou recebem ao mesmo tempo, resultando em um resultado imprevisível. Portanto, ao usar ponteiros ou referências em canais, deve-se assegurar que eles sejam acessados por apenas uma goroutine por vez.
Mycannel <- elemento
A frase acima indica que os dados (elemento) foram<-com a ajuda do operador de envio para o canal (Mycannel).
Operação de recebimento:A operação de recebimento é usada para receber os dados enviados pelo remetente da operação de envio.
elemento := <-Mycannel
A frase acima indica que o elemento foi recebido do canal (Mycannel). Se o resultado da frase recebida não estiver disponível (não necessário usar), também é uma frase válida. Você também pode escrever a seguinte frase de recebimento:
<-Mycannel
package main import "fmt" func myfunc(ch chan int) { fmt.Println(234 + <-ch) } func main() { fmt.Println("Método principal iniciado") //Criar canal l ch := make(chan int) go myfunc(ch) ch <- 23 fmt.Println("Método principal finalizado") }
Saída:
Método principal iniciado 257 Método principal finalizado
Você também pode fechar o canal com a ajuda da função close(). Esta é uma função built-in que define um sinal de que não haverá mais valores a serem enviados para o canal.
Sintaxe:
close()
Você também pode usar o loop de faixa for para fechar o canal. Aqui, o goroutine receptor pode usar a sintaxe fornecida para verificar se o canal está aberto ou fechado:
ele, ok := <- Mycannel
Aqui, se o valor de ok for true, significa que o canal foi aberto, portanto, pode ser executada a operação de leitura. E, se o valor for false, significa que o canal já foi fechado, portanto, a operação de leitura não será executada.
//A explicação do programa Go como //Fechamento do canal usado //loop de range e função de fechamento package main import "fmt" func myfun(mychnl chan string) { for v := 0; v < 4; v++ { mychnl <- "w3codebox } close(mychnl) } func main() { //Criar canal c := make(chan string) // Uso de Goroutine go myfun(c) //Quando o valor de ok é true, significa que o canal foi aberto, permitindo o envio ou recebimento de dados //Quando o valor de ok é configurado como false, significa que o canal foi fechado for { res, ok := <-c if ok == false { fmt.Println("Fechamento do canal: ", ok) break } fmt.Println("Abertura do canal: ", res, ok) } }
Saída:
Abertura do canal: w3codebox: true Abertura do canal: w3codebox: true Abertura do canal: w3codebox: true Abertura do canal: w3codebox: true Fechamento do canal: false
Bloqueio de envio e recebimento:No canal, quando dados são enviados para o canal, o controle é bloqueado na instrução de envio até que outro goroutine leia os dados do canal. Da mesma forma, quando o canal recebe dados de um goroutine, a instrução de leitura é bloqueada até que outra instrução de goroutine seja executada.
Canal com zero valor: Canalo valor zero é nil.
Loop for no canal: O loop for pode percorrer os valores enviados no canal até que seja fechado.
Sintaxe:
for item := range Chnl { // A expressão... }
package main import "fmt" func main() { // Usar a função make() para criar um canal mychnl := make(chan string) // Goroutine anônima go func() { mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox close(mychnl) } //Usar loop for for res := range mychnl { fmt.Println(res) } }
Saída:
GFG gfg Geeks w3codebox
Comprimento do canal:No canal, você pode usarFunção len()Encontrar o comprimento do canal. Aqui, o comprimento representa o número de valores enfileirados no buffer do canal.
package main import "fmt" func main() { // Usar a função make() para criar um canal mychnl := make(chan string, 4) mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox // Usar a função len() para encontrar o comprimento do canal fmt.Println("Comprimento do canal: ", len(mychnl)) }
Saída:
Comprimento do canal: 4
Capacidade do canal:No canal, você pode usar a função cap() para encontrar a capacidade do canal. Aqui, a capacidade representa o tamanho do buffer.
package main import "fmt" func main() { // Usar a função make() para criar um canal mychnl := make(chan string, 4) mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox // Usar a função cap() para encontrar a capacidade do canal fmt.Println("Capacidade do canal: ", cap(mychnl)) }
Saída:
Capacidade do canal: 5
Select e instruções case em canais:No go语言中,a instrução select é semelhante a uma instrução switch sem parâmetros de entrada. No uso de canais, a instrução select executa uma única operação entre múltiplas operações fornecidas pelos blocos de caso.