AnyCompiler

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)
}
Output
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)
}
Output
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.