Като затворим канал указваме, че няма да изпращаме повече стойности по него. Така уведомяваме получателите по този канал, че сме приключили.
import "fmt"
В този пример ще използваме канала задачки, за да
съобщим от гозадачата main() каква работа има за
вършене на друга гозадача – работник. Когато нямаме
повече задачки за работника, ще затворим канала
задачки, с помощта на вградената функция close.
func main() {
задачки := make(chan int, 5)
готово := make(chan bool)
Ето я гозадачата работник. Тя получава многократно
съобщения по канала задачки чрез изявлението з,
още := <-задачки. При този особен вид получаване с
две стойности, стойността в променливата още ще
бъде false, ако каналът задачки е затворен и
всички стойности от канала вече са получени.
Използваме този прийом, за да уведомим главната
гозадача по канала готово, че сме обработили
всички задачки.
go func() {
for {
з, още := <-задачки
if още {
fmt.Println("получих задачка", з)
} else {
fmt.Println("получих всички задачки")
готово <- true
return
}
}
}()
Чрез това повторение изпращаме три задачки по
канала задачки и след това го затваряме.
for з := 1; з <= 3; з++ {
задачки <- з
fmt.Println("изпратена задачка", з)
}
close(задачки)
fmt.Println("изпратени са всичи задачки")
Чакаме работника с помощта на канала за съгласуване1. Този способ за съгласуване го разгледахме вече.
<-готово
Четенето от затворен канал успява незабавно, като
връща нулевата стойност на основния вид данни за
този канал. Незадължителната втора върната стойност
е true, ако получената стойност е доставена чрез
успешно действие за изпращане по канала, или
false, ако получената нулева стойност е такава,
защото каналът е вече затворен и празен.
оз, имаОще := <-задачки
fmt.Println("има още задачки:", оз, имаОще)
}
$ go run closing-channels.go
изпратена задчка 1
изпратена задчка 2
изпратена задчка 3
изпратени са всичи задачки
получих задачка 1
получих задачка 2
получих задачка 3
получих всички задачки
има още задачки: 0 false
Мисълта за затворени канали ни води естествено към
следващия ни пример – обхождане на канали с помощта на
range.
Следващ пример: Обхождане на стойности в канал.