Los waitGroups (vistos en la anterior clase), son una forma óptima y de alto rendimiento para manejar los goroutines, pero si queremos tener menos tiempo en el desarrollo y no hacerlo tan complicado, siempre es bueno utilizar los channels.

Channels

Un channel es un conducto en el cual solo se puede manejar un tipo de dato y se implementa del siguiente modo.

Creamos un channel:

c := make(chan string, 1)

El tipo de dato que va a pasar por el canal es un string , y el 1 es opcional pero es una buena práctica colocarlo ya que indica cuántos datos simultáneos va a manejar ese canal, sino lo indicamos va a manejar un valor dinámico.

Seguido de esto, vamos a crear una función, en la cual recibe un texto y un chanel .

func say(text string, c chan<- string){
	c <- text
}

c <- text , es para indicarle que vamos a añadir un dato, en este caso text de tipo string en ese channel .

Luego invocamos esa función con un go.

go say("Bye", c)

El código iría así:

package main

import "fmt"

func say(text string, c chan string){
	c <- text
}

func main(){

	c := make(chan string, 1)

	fmt.Println("Hello")
	go say("Bye", c)
	
}

Pero esto solo va a imprimir la goroutine de la función main que es Hello . Entonces, ¿cómo hacemos para que esta goroutine espere a que termine la goroutine del channel ?

Lo hacemos extrayendo el dato que agregamos en el channel:

fmt.Println(<- c)

<-c indica la salida del dato del canal.

El código quedaría del siguiente modo:

package main

import "fmt"

func say(text string, c chan string){
	c <- text
}

func main(){

	c := make(chan string, 1)

	fmt.Println("Hello")
	go say("Bye", c)

	fmt.Println(<- c)
	
}

Ahora sí imprime ambos strings de cada goroutine .