Нет, они не (или по крайней мере Вы не можете предположить, что они). Однако существуют некоторые приемы, чтобы сделать это атомарно, но они обычно не являются портативными (см. Сравнивать-и-подкачивать ).
Вы можете использовать шаблон «запятая, хорошо» (см. Их страницу на « эффективный ход »):
foo := <- ch; // This blocks.
foo, ok := <- ch; // This returns immediately.
Вы также можете заглянуть в буфер канала, чтобы увидеть, содержит ли он что-нибудь, используя len:
if len(channel) > 0 {
// has data to receive
}
Это не коснется буфера канала, в отличие от foo, gotValue: = < - ch
, который удаляет значение, когда gotValue == true
.
Операторы выбора позволяют вам проверять несколько каналов одновременно, выбирая случайную ветвь (из тех, где ожидает связь):
func main () {
for {
select {
case w := <- workchan:
go do_work(w)
case <- signalchan:
return
// default works here if no communication is available
default:
// do idle work
}
}
}
Для всех отправляемых и получаемых выражения в операторе select, выражения канала оцениваются, вместе с любыми выражениями, которые появляются в правой части отправки выражения в порядке сверху вниз. Если какая-либо из результирующих операций может продолжаем, один выбран и соответствующее сообщение и заявления оцениваются. Иначе, если есть случай по умолчанию, это выполняет; если нет, оператор блокирует пока одно из сообщений не сможет завершено.