Channels
Um channel é um pipe tipado para enviar valores entre goroutines. msg := <-messages bloqueia até que um valor seja enviado naquele channel, e é exatamente assim que as duas goroutines no exemplo abaixo se coordenam sem nenhuma variável compartilhada ou lock.
package main
import "fmt"
func main() {
messages := make(chan string)
go func() {
messages <- "hello from a goroutine"
}()
msg := <-messages
fmt.Println(msg)
}hello from a goroutine
Um exemplo real: somando concorrentemente
sum roda como sua própria goroutine e envia seu resultado de volta por result assim que termina — main bloqueia em <-result até aquele valor chegar. Essa transferência baseada em channel é a alternativa idiomática do Go a compartilhar memória manualmente entre goroutines e protegê-la com locks.
package main
import "fmt"
func sum(numbers []int, result chan<- int) {
total := 0
for _, n := range numbers {
total += n
}
result <- total
}
func main() {
result := make(chan int)
go sum([]int{1, 2, 3, 4, 5}, result)
fmt.Println(<-result)
}15
A seguir: struct embedding — a forma do Go de construir composição em vez de herança de classes.
Practice exercise
Crie um channel ch := make(chan string). Inicie uma goroutine que envie "done" em ch, depois receba e imprima o valor de ch em main.