🔗 Что такое канал?
Каналы — это способ обмена данными между горутинами. Они позволяют синхронизировать выполнение и передавать значения.
Объявление канала:
ch := make(chan int) // канал для передачи int
📤 Отправка и приём
Отправка значения в канал:
ch <- 42Приём значения из канала:
value := <-ch
Эти операции блокируются, пока другая сторона не выполнит противоположную операцию.
🧵 Пример: обмен значением
func worker(ch chan string) {
    msg := <-ch
    fmt.Println("Получено:", msg)
}
func main() {
    ch := make(chan string)
    go worker(ch)
    ch <- "Привет, горутина!"
    time.Sleep(time.Second)
}
📚 Буферизированные каналы
Можно создать канал с буфером:
ch := make(chan int, 2)
Теперь можно отправить два значения без блокировки:
ch <- 1
ch <- 2
Третья отправка будет ждать, пока кто-то не прочитает значение из канала.
🚪 Закрытие канала
Канал можно закрыть, чтобы сообщить, что больше не будет значений:
close(ch)
При чтении из закрытого канала возвращается нулевое значение типа и false:
val, ok := <-ch
if !ok {
    fmt.Println("Канал закрыт")
}
📌 Главное из главы
- Каналы — способ общения между горутинами.
 - Они синхронизируют передачу значений.
 - Бывают буферизированные и небуферизированные.
 - Закрытие канала — важный инструмент завершения обмена.
 
В следующей главе ты узнаешь, как использовать шаблоны конкурентности, чтобы писать безопасный и эффективный параллельный код.