Отрывается ли оператор break от переключателя / выбора?

151

Я знаю, что операторы switch/ selectавтоматически прерываются после каждого случая. Мне интересно, в следующем коде:

for {
    switch sometest() {
    case 0:
        dosomething()
    case 1:
        break
    default:
        dosomethingelse()
    }
}

Имеет ли breakвыход заявление в forпетлю или только switchблок?

Мэтт
источник

Ответы:

204

Операторы разрыва, Спецификация языка программирования Go.

Оператор «break» завершает выполнение самого внутреннего оператора «for», «switch» или «select».

BreakStmt = "break" [ Label ] .

Если есть метка, то это должна быть метка включающего оператора «for», «switch» или «select», и это тот, выполнение которого завершается (операторы §For, операторы §Switch, операторы §Select).

L:
  for i < n {
      switch i {
      case 5:
          break L
      }
  }

Следовательно, breakоператор в вашем примере завершает switchоператор, «самый внутренний» оператор.

Питер SO
источник
8
Каков вариант использования breakвнутри, если можно выбрать select {}только одно case?
Хулио Герра
5
Потому что даже если выбран один случай, у него может быть более длинная реализация, которая использует break для прекращения выполнения дела, так же, как вы можете вернуться из любого места в функции.
Тит Петрик
Разве это не было бы плохим дизайном? потому что инструкция go to - плохой дизайн, а операторы switch / select автоматически
прерываются,
60

Надеюсь, показательный пример:

loop:
for {
        switch expr {
        case foo:
                if condA {
                        doA()
                        break // like 'goto A'
                }

                if condB {
                        doB()
                        break loop // like 'goto B'                        
                }

                doC()
        case bar:
                // ...
        }
A:
        doX()
        // ...
}

B:
doY()
// ....
zzzz
источник
15

Да breakломается внутреннее switch.

https://play.golang.org/p/SZdDuVjic4

package main

import "fmt"

func main() {

myloop:
    for x := 0; x < 7; x++ {
        fmt.Printf("%d", x)
        switch {
        case x == 1:
            fmt.Println("start")
        case x == 5:
            fmt.Println("stop")
            break myloop
        case x > 2:
            fmt.Println("crunching..")
            break
        default:
            fmt.Println("idling..")
        }
    }
}
0idling..
1start
2idling..
3crunching..
4crunching..
5stop

Program exited.
анатолий техтоник
источник
2

это должно объяснить это.

for{
    x := 1
    switch {
    case x >0:
        fmt.Println("sjus")
    case x == 1:
        fmt.Println("GFVjk")
    default:
        fmt.Println("daslkjh")
    }
}
}

Бежит вечно

for{
    x := 1
    switch {
    case x >0:
        fmt.Println("sjus")
        break
    case x == 1:
        fmt.Println("GFVjk")
    default:
        fmt.Println("daslkjh")
    }
}
}

Опять бежит вечно

НО

package main

import "fmt"

func main() {
d:
for{
x := 1
    switch {
    case x >0:
        fmt.Println("sjus")
        break d
    case x == 1:
        fmt.Println("GFVjk")
    default:
        fmt.Println("daslkjh")
    }
}
}

напечатает сюс ... ясно?

http://play.golang.org/p/GOvnfI67ih

Джасмит Сингх
источник
3
хммм, я добавил ссылку на игру, которая может быть полезна.
Jasmeet Singh 01
0

Он только выходит из блока переключателей.

Себастьян
источник
0

Этот вопрос может быть уже слишком старым, но я все же думаю, что ярлык затрудняет чтение нашего кода. Вместо того, чтобы нарушать внутренний выбор for, просто установите флаг для цикла и обработайте его внутри select-case перед вызовом break. Например:

loop := true
for loop {
    select {
    case <-msg:
        // do your task here
    case <-ctx.Done():
        loop = false
        break
    }
}
HaiTH
источник