小心break🤦‍♂️

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
查看执行结果
tick
tick
exiting...
tick
tick
1
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
查看执行结果
tick
tick
exiting...
exit!
1
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
查看执行结果
tick
tick
exiting...
exit!
1
2
3
4

代码执行到goto loop时,程序将跳转到loop所指的位置继续执行

最近更新时间: 7/26/2023, 6:37:16 AM
什么鸟日子
蒙太奇