golang 循环中的 switch 里的 break 与 continue

2022-09-28 11:18:31 浏览数 (1)

  最近在测试服务器的 UDP 接口, 最开始我使用 python 协程制造负载, 但是单机负载一直不高. 刚好最近在学习 golang 相关的内容, 就用 golang 实现了一个 UDP 施压的程序. 在编写 golang 程序的过程中经常要用到 goroutine 与 channel. 读取 channel 中的内容是阻塞的, 而且官方似乎没有给出相关的超时处理, 因此需要程序员做相关的超时处理. 一般用 select time.After() 进行超时处理. 代码如下:

代码语言:javascript复制
func main() {
	go sendToMain()

	for {
		fmt.Println("run for")
		//两个 case. 一个是从管道里面读数据, 另一个是 0.5s 执行.
		//当 0.5 秒内未在第一个 case 读取数据时执行第二个 case.
		select {
		case send_data := <-send_to_main: // 阻塞直到管道可读
			fmt.Println("run send_data := <-send_to_main case")
			switch send_data {
			case 1:
				fmt.Println("1")
			default:
				continue
			}
		case <-time.After(500 * time.Millisecond): // 0.5s 后管道还不可读则执行这个 case
			fmt.Println("run <-time.After(500 * time.Millisecond) case")
			break
		}
	}
}

  运行之后我发现 switch 里的 continue 可以跳出本次循环, 但是 select 里的 break 只会结束本次循环, 并不会跳出最外层的 for 循环, 难道外循环还需要些循环控制相关的逻辑吗? 查询相关资料后我发现并不用, 只需在 for 循环上加一个标签, break 到这个标签即可. 代码如下:

代码语言:javascript复制
var send_to_main = make(chan int)

func sendToMain() {
	for i := 0; i < 10; i   {
		send_to_main <- i
		time.Sleep(1 * time.Second) //阻塞 1 秒
	}
}

func main() {
	go sendToMain()

SELECT:
	for {
		fmt.Println("run for")
		//两个 case. 一个是从管道里面读数据, 另一个是 0.5s 执行.
		//当 0.5 秒内未在第一个 case 读取数据时执行第二个 case.
		select {
		case send_data := <-send_to_main: // 阻塞直到管道可读
			fmt.Println("run send_data := <-send_to_main case")
			switch send_data {
			case 1:
				fmt.Println("1")
			default:
				// continue SELECT
				continue
			}
		case <-time.After(500 * time.Millisecond): // 0.5s 后管道还不可读则执行这个 case
			fmt.Println("run <-time.After(500 * time.Millisecond) case")
			break SELECT
		}
	}
}

我刚刚接触 golang 写的比较简陋, 园里的大佬肯定有更好的方法, 希望各位大佬不吝赐教.

0 人点赞