小心break🤦♂️
hexiaopi 2/11/2023 Go基础
这里展示break的一个例子
package main
import (
"fmt"
"time"
)
func main() {
exit := make(chan interface{})
go func() {
for {
select {
case <-time.After(time.Second):
fmt.Println("tick")
case <-exit:
fmt.Println("exiting...")
break
}
}
fmt.Println("exit!")
}()
time.Sleep(3 * time.Second)
exit <- struct{}{}
// wait child goroutine exit
time.Sleep(3 * time.Second)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
查看执行结果
tick
tick
exiting...
tick
tick
1
2
3
4
5
2
3
4
5
按道理当收到exit信号时,协程应该退出,但此时协程仍旧在打印tick
其实break语句只是跳出最内部的for、swich或select的执行。例子中只是跳出了select语句,并未跳出for循环注意。这里并不是坑,只是如果从其他语言转到Go语言的童鞋,想当然的以为会跳到最外层,而事实是并没有。
那么我们该怎么跳到最外层呢?
1、通过break [label]
package main
import (
"fmt"
"time"
)
func main() {
exit := make(chan interface{})
go func() {
loop:
for {
select {
case <-time.After(time.Second):
fmt.Println("tick")
case <-exit:
fmt.Println("exiting...")
break loop
}
}
fmt.Println("exit!")
}()
time.Sleep(3 * time.Second)
exit <- struct{}{}
// wait child goroutine exit
time.Sleep(3 * time.Second)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
查看执行结果
tick
tick
exiting...
exit!
1
2
3
4
2
3
4
代码执行到break loop
时,程序将结束loop所指代的for循环的执行
2、通过goto [label]
package main
import (
"fmt"
"time"
)
func main() {
exit := make(chan interface{})
go func() {
for {
select {
case <-time.After(time.Second):
fmt.Println("tick")
case <-exit:
fmt.Println("exiting...")
goto loop
}
}
loop:
fmt.Println("exit!")
}()
time.Sleep(3 * time.Second)
exit <- struct{}{}
// wait child goroutine exit
time.Sleep(3 * time.Second)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
查看执行结果
tick
tick
exiting...
exit!
1
2
3
4
2
3
4
代码执行到goto loop
时,程序将跳转到loop所指的位置继续执行