Go роутины и каналы

Пример самого простого канала.

package main
import "time"
func main() {
	var message = make(chan string) // Создаём канал, что-бы складывать в него строки
	go func() {
		time.Sleep(time.Second * 1)
		message <- "Hello from goroutine" // Асинхрорнно пишем в канал
	}()
	print(<- message) // Ждём пока в канале что-то появиться и выводим
}

Немного усложнаем пример, теперь канал пишеться больше 1 раза. Закрываеться через close(канал) если не используется, и при получении сообщения мы проверяем открыт ли ещё канал или нет?

package main
import (
	"fmt"
	"time"
)
func main() {
	var message = make(chan string) // Создаём канал, что-бы складывать в него строки
	go func() {
		for i := 1; i <10; i++ {
			time.Sleep(time.Second)
			message <- fmt.Sprintf("Chan value %d", i) // Асинхрорнно пишем в канал
		}
		close(message) // Закрывем канал, в который больше нечего не запишится
	}()
	for {
		text, ok := <- message // Ждём пока в канале что-то появиться или канал закроется
		if !ok {
			break
		}
		println(text)
	}
}

Так-же есть синтаксический сахар для чтения канала

for text := range message { // Ждём пока в канале что-то появиться или канал закроется
	println(text)
}

Пример Буфферезированного канала, этот канал складывает данные а не ждёт выстрела

package main
func main() {
	var message = make(chan string, 2) // Создаём буфферизированный канал
	message <- "Привет"
	message <- "Мир"
	// message <- "!" // создаст deadlock, так как канал переполнен
	println(<- message)
	println(<- message)
}