Изпращането по канал и получаването по канал по
подразбиране спъва (блокира) главната нишка на
изпълнението. Въпреки това можем да използваме select
с допълнителна клауза – default1, за да
осъществим неспъващи изпращания,
получавания и дори неспъващи множествени избори2.
import "fmt"
func main() {
писма := make(chan string)
сигнали := make(chan bool)
Ето едно неспъващо получаване. Ако в канала писма
вече има стойност, тогава select ще влезе в
случая <-писма и ще вземе тази стойност. Иначе ще
влезе в подразбирания случай default.
select {
case писмо := <-писма:
fmt.Println("получено писмо:", писмо)
default:
fmt.Println("няма нови писма")
}
Неспъващото изпращане работи по подобен начин.
Тук писмо не може да бъде изпратено по канала
писма, защото каналът няма зададена вместимост
(значи не задържа) и няма получател. Затова бива
избран случаят default.
писмо := "hi"
select {
case писма <- писмо:
fmt.Println("изпратено писмо", писмо)
default:
fmt.Println("не е изпратено писмо")
}
Можем да имаме повече случаи над случая по
подразбиране default и така да осъществим
множествен неспъващ избор. Тук осъществяваме
неспъващ главната нишка избор от каналите писма и
сигнали.
select {
case писмо := <-писма:
fmt.Println("получено писмо", писмо)
case sig := <-сигнали:
fmt.Println("получен сигнал", sig)
default:
fmt.Println("бездействие")
}
}
$ go run non-blocking-channel-operations.go
няма нови писма
не е изпратено писмо
бездействие
Следващ пример: Затваряне на канали.