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
.
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
.