2016-07-12 5 views
2

Не удалось полностью понять это из документов или Google:В чем разница между циклами с выбором и только выбором?

В чем разница между ними и в В каком случае вы бы использовали каждый из них?

for{ 
     select{ 
     case s := <-something: 
      fmt.Println(s) 
     case done := <-true: 
      return 
     } 
    } 

и

 select{ 
     case s := <-something: 
      fmt.Println(s) 
     case done := <-true: 
      return 
     } 

Благодаря

ответ

7

код с петлей будет продолжайте печатать данные из канала somethingдо он получает что-либо на канале done.

Выберите только код либо печать данных из канала somethingили уйдет, когда он получает что-либо на канале done. Будет выполнен только один случай. Имейте в виду, что в Go select и switch заявления по умолчанию отсутствуют.

1

Если программа отправляет данные в канал «что-то» кучу раз вы собираетесь хотите повторить выберите пункт, пока вы не получите решенным сигнал.

Например представьте, что вы работаете в следующей рутине

.... (some calculations) 
something <- x 
.... (some calculations) 
something <- y 
true <- z 

Если ваша программа не имеет для цикла он получит только значение «х» и не получит у или г.

1

select заявление выполняется через его cases (отправка/получение канала) один раз. Если ни один из его случаев не готов к выполнению, он блокируется, пока не будет выполнен хотя бы один из case. Если одновременно запускается несколько случаев, один из готовых кейсов выбирается для случайного выполнения.

Таким образом, во втором случае, если есть некоторые данные на канале something, он будет считан и помещен в s. Но есть также шанс, что true будет отправлен на done, а case s := <-something: никогда не будет выполнен.

В первом случае, вы, вероятно, хотите что-то вроде этого (и во втором случае):

for{ 
    select{ 
    case s := <-something: 
     fmt.Println(s) 
    case <-done: // note the difference 
     return 
    } 
} 

Что это сейчас делает то, что он ждет данных о something, а также следит за done. Если есть данные по каналу something (и данных нет на done), он будет считан и помещен в s (регистр case case s := <-something: будет выполнен с s, имеющий значение, считанное с something). Это будет учитывать одно полное выполнение инструкции select, и элемент управления вернется в цикл for, и он начнется снова.

Если нет данных по каналу something, select блоков и ожидает данных по обе something или done.Если данные поступают на something, выполняется аналогичное выполнение, как описано выше, в противном случае, если оно поступило в done, функция возвращает (выходит из цикла). Таким образом, какой-либо другой процесс может записать в done и передать функцию, содержащую выше for цикл, чтобы остановить обработку something и вернуться.