Go за Прикладом: Не Блокуючі Операції на Каналах

Базові надсилання та отримання на каналах це блокуючі операції. Однак, ми можемо використовувати select з умовою default для реалізації не блокуючих відправлень, і навіть для не блокуючих різнонаправлених selectів.

package main
import "fmt"
func main() {
    messages := make(chan string)
    signals := make(chan bool)

Ось не блокуюче отримання. Якщо значення доступне в каналі messages тоді select підбере умову <-messages в case з цим значенням. А якщо значення не доступне - то негайно буде обрана стандартна умова default.

    select {
    case msg := <-messages:
        fmt.Println("отримане повідомлення", msg)
    default:
        fmt.Println("жодних повідомлень не отримано")
    }

Не блокуючі надсилання працюють схожим чином, тут msg не може бути надіслано до каналу messages, тому що цей канал не є буферизованим і тому що немає отримувача. Саме тому відбудеться стандартна умова default.

    msg := "привіт"
    select {
    case messages <- msg:
        fmt.Println("надіслано повідомлення", msg)
    default:
        fmt.Println("жодних повідомлень не надіслано")
    }

Над стандартною умовою default дозволяється мати більш ніж одну умови, для імплементації різнонаправлених selectів, умови яких будуть чекати отримання як messages, так і signals.

    select {
    case msg := <-messages:
        fmt.Println("отримано повідомлення", msg)
    case sig := <-signals:
        fmt.Println("отриманий сигнал", sig)
    default:
        fmt.Println("жодної активності")
    }
}
$ go run non-blocking-channel-operations.go
жодних повідомлень не отримано
жодних повідомлень не надіслано
жодної активності

Наступний приклад: Закриття каналів.