English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
En el lenguaje Go, el canal es el medio de comunicación entre goroutine y otro goroutine, y esta comunicación es sin bloqueo. En otras palabras, el canal es una técnica que permite a un goroutine enviar datos a otro goroutine. Por defecto, el canal es bidireccional, lo que significa que un goroutine puede enviar o recibir datos a través del mismo canal, como se muestra en la siguiente figura:
En el lenguaje Go, se crea un canal utilizando la palabra clave chan, y el canal solo puede transmitir datos del mismo tipo, no se permite transmitir diferentes tipos de datos a través del mismo canal.
Sintaxis:
var Channel_name chan Type
También se puede usar una declaración abreviada para crear un canal a través de la función make().
Sintaxis:
channel_name:= make(chan Type)
package main import "fmt" func main() { //Se crea un canal utilizando la palabra clave var var mychannel chan int fmt.Println("channel的值: ", mychannel) fmt.Printf("channel的类型: %T ", mychannel) // Usar la función make() para crear un canal mychannel1 := make(chan int) fmt.Println("\nchannel1El valor: ", mychannel1) fmt.Printf("channel1El tipo: %T "1) {}
Salida:
El valor del canal: <nil> El tipo del canal: chan int Canales1El valor: 0xc0000160c0 Canales1El tipo: chan int
En el lenguaje Go, el trabajo de los canales tiene dos operaciones principales, una es enviar y la otra es recibir, estas dos operaciones se denominan en conjunto comunicación.-La dirección del operador indica si se está recibiendo o enviando datos. En los canales, por defecto, las operaciones de envío y recepción se bloquean hasta que el otro extremo no tenga datos. Esto permite que las goroutines se sincronicen entre sí sin locks explícitos o variables de condición.
Operación de envío:La operación de envío se utiliza para enviar datos de una goroutine a otra a través de canales. Como int, float64Los valores como bool pueden enviarse de manera segura y fácil a través de canales, ya que se copian, por lo que no existe el riesgo de acceso concurrente a valores iguales. Del mismo modo, las cadenas de caracteres también son seguras, ya que son inmutables. Sin embargo, no es seguro enviar punteros o referencias (por ejemplo, cortes, conjuntos de mapas, etc.) a través de canales, ya que los valores de los punteros o referencias pueden cambiar a través de goroutines que envían o reciben simultáneamente, y los resultados son impredecibles. Por lo tanto, al usar punteros o referencias en canales, debe asegurarse de que solo puedan ser accedidos por una sola goroutine a la vez.
Mychannel <- element
上面的语句表明数据(element)在<-运算符的帮助下发送到通道(Mychannel)。
接收操作:接收操作用于接收发送操作方发送的数据。
element := <-Mychannel
上面的语句表明该元素从channel(Mychannel)接收数据。如果接收到的语句的结果不可用(不需要使用),则也是有效的语句。您还可以编写如下的receive语句:
<-Mychannel
package main import "fmt" func myfunc(ch chan int) { fmt.Println(234 + <-ch) {} func main() { fmt.Println("主方法开始") //创建通道l ch := make(chan int) go myfunc(ch) ch <- 23 fmt.Println("主方法结束") {}
Salida:
主方法开始 257 主方法结束
您也可以在close()函数的帮助下关闭通道。这是一个内置函数,并设置一个标识,表示不再有任何值将发送到该通道。
Sintaxis:
close()
您也可以使用for范围循环关闭通道。在这里,接收器goroutine可以借助给定的语法检查通道是打开还是关闭:
ele, ok := <- Mychannel
在此,如果ok的值为true,则表示通道已打开,因此可以执行读取操作。并且,如果的值为false,则表示该通道已关闭,因此将不执行读取操作。
//Go程序说明如何 //关闭使用的通道 //range循环和关闭函数 package main import "fmt" func myfun(mychnl chan string) { for v := 0; v < 4; v++ { mychnl <- "w3codebox {} close(mychnl) {} func main() { //创建通道 c := make(chan string) // 使用 Goroutine go myfun(c) //当ok的值为为true时,表示通道已打开,可以发送或接收数据 //当ok的值设置为false时,表示通道已关闭 for { res, ok := <-c if ok == false { fmt.Println("Cierre del canal ", ok) break {} fmt.Println("Canal abierto ", res, ok) {} {}
Salida:
Canal abierto w3codebox true Canal abierto w3codebox true Canal abierto w3codebox true Canal abierto w3codebox true Cierre del canal false
Bloquear envío y recepción:En el canal, cuando se envía datos al canal, el control se bloquea en la sentencia de envío hasta que otro goroutine lea datos del canal. De manera similar, cuando el canal recibe datos de un goroutine, la sentencia de lectura se bloquea hasta que otra sentencia de goroutine lo lea.
Canal de valor cero: Canalel valor cero es nil.
Bucle for en el canal: El bucle for puede recorrer los valores ordenados enviados en el canal hasta que se cierre.
Sintaxis:
for item := range Chnl { // expresión... {}
package main import "fmt" func main() { // Usar la función make() para crear un canal mychnl := make(chan string) // Goroutine anónima go func() { mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox close(mychnl) }() //Usar el bucle for for res := range mychnl { fmt.Println(res) {} {}
Salida:
GFG gfg Geeks w3codebox
Longitud del canal:En el canal, puedes usarFunción len()Encontrar la longitud del canal. Aquí, la longitud representa la cantidad de valores en cola en el buffer del canal.
package main import "fmt" func main() { // Usar la función make() para crear un canal mychnl := make(chan string, 4) mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox // Usar la función len() para encontrar la longitud del canal fmt.Println("La longitud del canal es: ", len(mychnl)) {}
Salida:
La longitud del canal es: 4
Capacidad del canal:En el canal, puedes usar la función cap() para encontrar la capacidad del canal. Aquí, la capacidad representa el tamaño del buffer.
package main import "fmt" func main() { // Usar la función make() para crear un canal mychnl := make(chan string, 4) mychnl <- "GFG" mychnl <- "gfg" mychnl <- "Geeks" mychnl <- "w3codebox // Usar la función cap() para encontrar la capacidad del canal fmt.Println("La capacidad del canal es: ", cap(mychnl)) {}
Salida:
La capacidad del canal es: 5
Select y la sentencia case en el canal:En el lenguaje Go, la sentencia select es similar a una sentencia switch sin parámetros de entrada. Al usar la sentencia select en los canales, se ejecuta una sola operación de entre las múltiples proporcionadas por los bloques case.