Closing Channels

Закриття каналів|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` з каналами.