GO: for-select 下的 break,continue 和 return

313 阅读1分钟

前言

本文主要对 Go 语言 for-select 嵌套下 breakcontinuereturn 的行为进行测试以及记录。

break

break 后退出当前的 select 并继续执行 for 以内 select 以后的其他代码;不会打断外层 for 循环。

如果想要退出外层 for 循环需要使用 label,示例代码如下:

package main

import (
	"fmt"
	"time"
)

func main() {
	ch1 := make(chan struct{})
	go func() {
		time.Sleep(time.Second * 3)
		ch1 <- struct{}{}
	}()
LOOP:
	for {
		select {
		case <-ch1:
			fmt.Println("<-ch1")
			break LOOP
		default:
			time.Sleep(time.Second * 1)
			fmt.Println("default")
		}
		fmt.Println("for")
	}
}

测试代码

package main

import (
	"fmt"
	"time"
)

func main() {
	ch := make(chan struct{})
	go func() {
		time.Sleep(time.Second * 3)
		ch <- struct{}{}
	}()
	for {
		select {
		case <-ch:
			fmt.Println("<-ch")
			break
		default:
			time.Sleep(time.Second * 1)
			fmt.Println("default")
		}
		fmt.Println("for")
	}
}

运行结果

default
for
default
for
default
for
<-ch
for 
default
for
default
for
default
for
...

continue

continue 后继续执行其他 select 中可以运行的 case 以及 select 以后的其他代码,如果没有其他可以运行的 case 则执行 default;不会打断外层 for 循环。

测试代码

package main

import (
	"fmt"
	"time"
)

func main() {
	ch1 := make(chan struct{})
	ch2 := make(chan struct{})
	go func() {
		time.Sleep(time.Second * 3)
		ch1 <- struct{}{}
	}()
	go func() {
		time.Sleep(time.Second * 4)
		ch2 <- struct{}{}
	}()
	for {
		select {
		case <-ch1:
			fmt.Println("<-ch1")
			time.Sleep(time.Second * 2)
			continue
		case <-ch2:
			fmt.Println("<-ch2")
			continue
		default:
			time.Sleep(time.Second * 1)
			fmt.Println("default")
		}
		fmt.Println("for")
	}
}

运行结果

for
default
for
default
for  
<-ch1
<-ch2
default
for
default
for    
default
for
default
for
...

return

return 后直接返回,没什么好说的。

测试代码

package main

import (
	"fmt"
	"time"
)

func main() {
	ch1 := make(chan struct{})
	go func() {
		time.Sleep(time.Second * 3)
		ch1 <- struct{}{}
	}()
	for {
		select {
		case <-ch1:
			fmt.Println("<-ch1")
			return
		default:
			time.Sleep(time.Second * 1)
			fmt.Println("default")
		}
		fmt.Println("for")
	}
}

运行结果

default
for
default
for    
default
for  
<-ch1

总结

与未测试前的想象有点不同,需要注意。