Закриття каналів|Closing Channels
#
// _Закриття_ каналу вказує на те, що більше жодних значень
// в нього відправлено не буде. Це стає в нагоді при передачі
// повідомлення про завершення до отримувачів каналу.
package main
import "fmt"
func main() {
// В цьому прикладі ми скористаємось каналом `jobs` для
// комунікації задач між горутиною в `main()` та робочою горутиною.
// Коли роботи більше немає - ми закриємо канал `jobs` за допомогою `close`.
jobs := make(chan int, 5)
done := make(chan bool)
// Це робоча горутина, вона безперервно отримує з каналу
// `jobs` завдання (за допомогою `j, more := <-jobs`).
// У цій конструкції якщо `more` буде `false` канал `jobs`
// закриється і всі значення з нього будуть вийняті.
// Ми скористаємось цим для відправки в канал `done`
// повідомлення що завдання закінчені і програма може
// завершити свою роботу.
go func() {
for {
j, more := <-jobs
if more {
fmt.Println("отримане завдання", j)
} else {
fmt.Println("усі завдання отримані")
done <- true
return
}
}
}()
// Оце надішле 3 задачі до робочої горутини через канал
// `jobs`, після чого закриє його.
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("надіслано завдання", j)
}
close(jobs)
fmt.Println("усі завдання надіслані")
// Ми чекаємо коли горутина робітник використає
// [синхронізацію](channel-synchronization) що
// ми бачили раніше.
<-done
}
$ go run closing-channels.go
надіслано завдання 1
надіслано завдання 2
надіслано завдання 3
усі завдання надіслані
отримане завдання 1
отримане завдання 2
отримане завдання 3
усі завдання отримані
# Ідея закритих каналів приводить нас до
# наступного прикладу: використання `range` з каналами.