英文:
Does a break statement break from a switch/select?
问题
我知道switch
/select
语句在每个case之后会自动中断。我想知道,在下面的代码中:
for {
switch sometest() {
case 0:
dosomething()
case 1:
break
default:
dosomethingelse()
}
}
break
语句是退出for
循环还是只是退出switch
块?
英文:
I know that switch
/select
statements break automatically after every case. I am wondering, in the following code:
for {
switch sometest() {
case 0:
dosomething()
case 1:
break
default:
dosomethingelse()
}
}
Does the break
statement exit the for
loop or just the switch
block?
答案1
得分: 277
> Break语句,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
语句,即最内层的语句。
1: http://golang.org/ref/spec#Break_statements
英文:
> Break statements, The Go Programming Language Specification.
>
> A "break" statement terminates execution of the innermost "for",
> "switch" or "select" statement.
>
> BreakStmt = "break" [ Label ] .
>
> If there is a label, it must be that of an enclosing "for", "switch"
> or "select" statement, and that is the one whose execution terminates
> (§For statements, §Switch statements, §Select statements).
>
> L:
> for i < n {
> switch i {
> case 5:
> break L
> }
> }
Therefore, the break
statement in your example terminates the switch
statement, the "innermost" statement.
1: http://golang.org/ref/spec#Break_statements
答案2
得分: 85
一个希望能够说明问题的例子:
循环:
for {
switch expr {
case foo:
if condA {
doA()
break // 类似于 'goto A'
}
if condB {
doB()
break loop // 类似于 'goto B'
}
doC()
case bar:
// ...
}
A:
doX()
// ...
}
B:
doY()
// ....
英文:
A hopefully illustrative example:
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()
// ....
答案3
得分: 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("开始")
case x == 5:
fmt.Println("停止")
break myloop
case x > 2:
fmt.Println("处理中...")
break
default:
fmt.Println("空闲中...")
}
}
}
输出结果:
0空闲中...
1开始
2空闲中...
3处理中...
4处理中...
5停止
程序已退出。
英文:
Yes, break
breaks the inner switch
.
https://play.golang.org/p/SZdDuVjic4
<!-- language: go -->
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.
答案4
得分: 22
这个问题可能已经太旧了,但我仍然认为标签使我们的代码变得更难阅读。
不要在select内部中断循环,只需在调用break之前在select-case中设置一个循环标志并处理它。
例如:
loop := true
for loop {
select {
case <-msg:
// 在这里执行任务
case <-ctx.Done():
loop = false
break
}
}
**更新:**完全同意评论中的Vaelin的观点。在for循环的作用域内声明该标志可以避免内存泄漏,并且可以避免与当前作用域中的其他变量冲突,以防我们已经有一个同名变量。
for loop := true; loop; {
}
英文:
This question might be too old already but I still think label makes our code become harder to read.
Instead of breaking the for inside select, just set a flag for the loop and handle it inside select-case before invoking break.
For example:
loop := true
for loop {
select {
case <-msg:
// do your task here
case <-ctx.Done():
loop = false
break
}
}
Updated: Totally agree with Vaelin in the comment. Declaring that flag inside the scope of the for loop can avoid memory leak and conflict with other variables in current scope, just in case we have a same variable name already.
for loop := true; loop; {
}
答案5
得分: 8
只从一个switch块中退出。在Golang自己的代码中有很多例子可以检查(比较内部break和外部break)。
英文:
Just from a switch block. There's plenty of examples in Golang own code you can examine (compare inner break with outer break).
答案6
得分: 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
英文:
this should explain it.
for{
x := 1
switch {
case x >0:
fmt.Println("sjus")
case x == 1:
fmt.Println("GFVjk")
default:
fmt.Println("daslkjh")
}
}
}
Runs forever
for{
x := 1
switch {
case x >0:
fmt.Println("sjus")
break
case x == 1:
fmt.Println("GFVjk")
default:
fmt.Println("daslkjh")
}
}
}
Again, runs forever
BUT
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")
}
}
}
will print sjus
... clear ?
答案7
得分: 0
只有退出开关块。
英文:
It only exits the switch block.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论