# select утверждения (select statements)

**Утверждение "select"** выбирает, какой из набора возможных операций отправки или получения будет продолжен. Это похоже на утверждние "switch", но со всеми случаями (cases), относящимися к операциям связи.

```
SelectStmt = "select" "{" { CommClause } "}" .
CommClause = CommCase ":" StatementList .
CommCase   = "case" ( SendStmt | RecvStmt ) | "default" .
RecvStmt   = [ ExpressionList "=" | IdentifierList ":=" ] RecvExpr .
RecvExpr   = Expression .
```

Случай (case) с RecvStmt может присвоить результат RecvExpr одной или двум переменным, которые могут быть объявлены с помощью краткого объявления переменных. RecvExpr должен быть (возможно заключенной в скобки) операцией приема. Может быть не более одного случая по умолчанию, и он может появиться в любом месте списка случаев (cases).

Исполнение утверждения "select" происходит в несколько этапов:

1. Для всех случаев в утверждении операнды канала операций приема и выражения канала и правой части выражений утверждений отправки оцениваются ровно один раз в порядке исходного кода при входе в "select" утверждение. Результатом является набор каналов для приема или отправки и соответствующие значения для отправки. Любые побочные эффекты в этой оценке будут иметь место независимо от того, какая (если таковая имеется) операция связи выбрана для продолжения. Выражения в левой части RecvStmt с кратким объявлением или присваиванием переменной еще не оценены.
2. Если одно или несколько сообщений может быть продолжено, выбирается одно, которое может продолжаться, посредством равномерного псевдослучайного выбора. В противном случае, если есть случай по умолчанию, этот случай выбирается. Если случай по умолчанию отсутствует, утверждение "select" блокируется до тех пор, пока не будет продолжено хотя бы одно из сообщений.
3. Если выбранный случай не является случаем по умолчанию, выполняется соответствующая операция связи.
4. Если выбранный случай представляет собой RecvStmt с коротким объявлением переменной или присваиванием, левые выражения оцениваются и присваивается полученное значение (или значения).
5. Список выписок выбранного случая выполнен.

Поскольку обмен данными по нулевым каналам никогда не может быть продолжен, select только с нулевыми каналами и без случая по умолчанию блокируется навсегда.

```
var a []int
var c, c1, c2, c3, c4 chan int
var i1, i2 int
select {
case i1 = <-c1:
  print("received ", i1, " from c1\n")
case c2 <- i2:
  print("sent ", i2, " to c2\n")
case i3, ok := (<-c3):  // то же самое что и: i3, ok := <-c3
  if ok {
    print("received ", i3, " from c3\n")
  } else {
    print("c3 is closed\n")
  }
case a[f()] = <-c4:
  // то же самое что и:
  // case t := <-c4
  //  a[f()] = t
default:
  print("no communication\n")
}

for {  // отправляет случайную последовательность битов в c
  select {
  case c <- 0:  // примечание: нет утверждения, нет fallthrough ("провала" в следующий случай), нет сворачивания случаев
  case c <- 1:
  }
}

select {}  // блокируется навсегда
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://folko.gitbook.io/goland/specifikaciya-1/select-utverzhdeniya-select-statements.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
