Saltar al contenido principal
eLearner.app
Módulo 7 · Lección 2 de 532/50 en el curso~15 min
Lecciones del módulo (2/5)

Canales: comunicación tipada

Los canales son el mecanismo idiomático de comunicación entre gorutinas. La filosofía Go (Rob Pike):

"No comuniques compartiendo memoria; comparte memoria comunicando."

Un canal es una cola FIFO escrita, de tipo seguro y segura para concurrencia. uso. Combinado con go, es el componente principal de Go. concurrencia.

Crear, enviar, recibir

Go
ch := make(chan int)     // canale di int, unbuffered

go func() {
    ch <- 42             // invia (può bloccare)
}()

v := <-ch                // ricevi (può bloccare)
fmt.Println(v)           // 42

Sintaxis:

  • make(chan T) o make(chan T, N) para buffer.
  • ch <- v envía.
  • v := <-ch recibe.
  • v, ok := <-ch recibe con una bandera (ok = false si el canal está cerrado Y vacío).

Sin búfer: encuentro

Un canal sin búfer (capacidad 0) bloquea:

  • el remitente hasta que un receptor esté listo;
  • el receptor hasta que un remitente esté listo.

Es una cita sincrónica: útil como "señal" o para garantizar que el valor ha sido entregado.

Buffered: cola hasta N

Go
ch := make(chan int, 3)
ch <- 1   // non blocca
ch <- 2   // non blocca
ch <- 3   // non blocca
ch <- 4   // BLOCCA: il buffer è pieno

El remitente bloquea sólo cuando el búfer está lleno; el receptor solamente cuando está vacío.

cerca y a distancia

El remitente cierra el canal cuando no hay más valores:

Go
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)

for v := range ch {      // termina quando ch è chiuso E vuoto
    fmt.Println(v)
}

for range sobre un canal se itera hasta que el canal se cierra (y se drena). Es el patrón más limpio para “consumir todo lo que llega”.

Direccionalidad en firmas

Los parámetros de función pueden restringir la dirección:

Go
func producer(out chan<- int) {   // solo invio
    out <- 1
    close(out)
}

func consumer(in <-chan int) {    // solo ricezione
    for v := range in {
        fmt.Println(v)
    }
}

chan<- T = solo envío, <-chan T = solo recepción. Un bidireccional El canal chan T se puede pasar a cualquiera de los dos (conversión implícita). eso mejora la claridad y previene errores.

Patrones comunes (vista previa)

  • Grupo de trabajadores: N gorutinas consumen desde jobs <-chan T, producen en results chan<- R.
  • Pipeline: etapas conectadas por canales.
  • Señal hecho: un canal chan struct{} cerrado para señal de "parada".
Go
done := make(chan struct{})
go func() {
    <-done    // blocca finché qualcuno chiude done
    cleanup()
}()
close(done)   // segnale di stop

chan struct{} es el canal de "señal": cero bytes de carga útil, solo sincronización.

Pruébalo

Ejercicio#go.m7.l2.e1
Intentos: 0Cargando...

Cree un canal int sin búfer, envíe 42 desde una rutina, recíbalo en principal e imprímalo.

Cargando editor...
Mostrar pista

Sin un búfer, el remitente y el receptor se sincronizan.

Solución disponible después de 3 intentos

Ejercicio#go.m7.l2.e2
Intentos: 0Cargando...

Envíe 1,2,3 a través de un canal almacenado en búfer, ciérrelo y luego imprima todo con for-range.

Cargando editor...
Mostrar pista

`for range` sobre un canal termina cuando el canal se cierra y se drena.

Solución disponible después de 3 intentos

Cuestionario#go.m7.l2.e3
Listo

¿Qué hace un canal SIN BUFFERED cuando el remitente envía pero ningún receptor está listo?

Go
ch := make(chan int)
ch <- 1 // ?
Opciones de respuesta

Resumen

  • Canal = cola FIFO escrita, segura entre gorutinas.
  • Sin búfer: encuentro (el remitente y el receptor se sincronizan).
  • Buffered: desacoplamiento, se bloquea solo cuando está lleno/vacío.
  • close(ch): sólo el remitente; for range consume hasta cerrar.
  • Direccionalidad: chan<- T (solo envío), <-chan T (solo recepción).
  • chan struct{} como canal de señal para sincronización pura.