break语句在switch/select语句中是否会跳出循环?

213

我知道在switch/select语句中,每个case执行完后会自动跳出。但是在下面的代码中:

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

break语句是用于跳出for循环或switch块的吗?

7个回答

280

中断语句,Go编程语言规范。

“break”语句终止最内层的“for”、“switch”或“select”语句的执行。

BreakStmt = "break" [ Label ] .

如果有一个标签,则它必须是封闭的“for”、“switch”或“select”语句的标签,并且正是执行该语句的标签终止了执行。

L:
  for i < n {
      switch i {
      case 5:
          break L
      }
  }
因此,你例子中的 break 语句终止了 switch 语句,也就是“最内层”的语句。

20
select {} 中使用 break 的用例是什么?因为只能选择一个 case - Julio Guerra
24
即使只选定一个单一的情况,它可能有更长的实现,使用“break”来终止该情况的执行,就像你可以从函数的任何地方返回一样。 - Tit Petric
还有可能n很大,所以你希望尽快跳出循环。 - undefined

87

一个希望有启发性的例子:

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()
// ....

27

是的,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.

6
这个回答没有展示出没有标签的 break 语句是如何有用的。在 case x > 2: 中的 break 语句实际上是一个无操作。 - HairOfTheDog

23

这个问题可能已经太旧了,但我仍然认为标签使我们的代码变得更难读。 不要打破选择中的for循环,只需为循环设置一个标志,并在调用break之前在select-case内处理它。 例如:

loop := true
for loop {
    select {
    case <-msg:
        // do your task here
    case <-ctx.Done():
        loop = false
        break
    }
}

更新:完全同意评论区Vaelin的观点。在for循环的作用域内声明标志可以避免内存泄漏和与当前作用域中其他变量的冲突,以防我们已经有了相同的变量名。

for loop := true; loop; {

}

11
如果你不想泄露循环变量,你也可以在for循环的作用域内声明它,例如:for loop := true; loop; {}。示例代码链接:https://play.golang.org/p/dNChUECkbfd - Vaelin

8

仅来自switch块。在Golang的源代码中,您可以查看大量示例(比较内部break外部break)。


3

这应该可以解释清楚。

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")
    }
}
}

将会打印sjus,明白吗?

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


4
我在其中包含了一个“去玩”链接,可能会很有帮助。 - Jasmeet Singh

0

它只退出了 switch 块。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接