在某佬交流群看到下面这样一段代码。
问,执行下面代码会出现什么现象?
func main() {
ac := make(chan int, 1)
ac <- 1
bc := make(chan int, 3)
bc <- 1
bc <- 2
for {
select {
case a := <-ac:
fmt.Println("from ac: ", a)
case b := <-bc:
fmt.Println("from bc: ", b)
default:
break
}
}
fmt.Println("do other thing")
fmt.Println("over")
}
A "break" statement terminates execution of the innermost "for", "switch", or "select" statement within the same function.
也就是说在select中,break会中止其后面语句的执行,但是并不会打断外层的for循环,所以上面的代码会打印完chan中数据后一直陷入死循环,那么解决方法有哪些呢?
A "continue" statement begins the next iteration of the innermost "for" loop at its post statement. The "for" loop must be within the same function.
continue语句会结束最内层的for循环。
for {
select {
case a := <-ac:
fmt.Println("from ac: ", a)
continue
case b := <-bc:
fmt.Println("from bc: ", b)
continue
default:
}
break
}
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.
break可以打断for,select,switch代码标签的运作,可以通过加个标签来退出循环。
forSelectLoop:
for {
select {
case a := <-ac:
fmt.Println("from ac: ", a)
case b := <-bc:
fmt.Println("from bc: ", b)
default:
break forSelectLoop
}
}
可以通过goto跳出循环。
for {
select {
case a := <-ac:
fmt.Println("from ac: ", a)
case b := <-bc:
fmt.Println("from bc: ", b)
default:
goto over
}
}
over:
fmt.Println("do other thing")
fmt.Println("over")
可以在for循环条件处做些标记。
var sign bool
for !sign {
select {
case a := <-ac:
fmt.Println("from ac: ", a)
case b := <-bc:
fmt.Println("from bc: ", b)
default:
sign = true
}
}
# https://go.dev/ref/spec#Break_statements