select 与 for 结合使用时,break 语句无法跳出循环
func TestBreakInSelectAndFor(t *testing.T) {
quitChan := make(chan bool)
runForever := make(chan bool)
go test(quitChan)
// after 10 second, close quit chan
<-time.After(time.Duration(10) * time.Second)
close(quitChan)
<-runForever
}
func test(quitChan chan bool) {
var (
interValTime = 4
sleepTime = 1
)
for {
select {
case <-time.After(time.Duration(interValTime) * time.Second):
log.Printf("select struct: get time chan every %v second interval\n", interValTime)
case <-quitChan:
log.Println("select struct: get quit signal, now prepare to jump out of the loop")
break
}
log.Printf("for struct: sleep %v second before start next loop\n", sleepTime)
time.Sleep(time.Duration(sleepTime) * time.Second)
}
log.Println("have jump out of the loop")
}
2019/02/28 18:35:03 select struct: get time chan every 4 second interval
2019/02/28 18:35:03 for struct: sleep 1 second before start next loop
2019/02/28 18:35:08 select struct: get time chan every 4 second interval
2019/02/28 18:35:08 for struct: sleep 1 second before start next loop
2019/02/28 18:35:09 select struct: get quit signal, now prepare to jump out of the loop
2019/02/28 18:35:09 for struct: sleep 1 second before start next loop
2019/02/28 18:35:10 select struct: get quit signal, now prepare to jump out of the loop
2019/02/28 18:35:10 for struct: sleep 1 second before start next loop
...
从执行的结果可以看出,select 中的 break 并没有跳出循环。其实只是跳出了 select struct。
跳出循环的几种方式
break label
func test(quitChan chan bool) {
var (
interValTime = 4
sleepTime = 1
)
forEnd:
for {
select {
case <-time.After(time.Duration(interValTime) * time.Second):
log.Printf("select struct: get time chan every %v second interval\n", interValTime)
case <-quitChan:
log.Println("select struct: get quit signal, now prepare to jump out of the loop")
break forEnd
}
log.Printf("for struct: sleep %v second before start next loop\n", sleepTime)
time.Sleep(time.Duration(sleepTime) * time.Second)
}
log.Println("have jump out of the loop")
}
2019/02/28 18:42:24 select struct: get time chan every 4 second interval
2019/02/28 18:42:24 for struct: sleep 1 second before start next loop
2019/02/28 18:42:29 select struct: get time chan every 4 second interval
2019/02/28 18:42:29 for struct: sleep 1 second before start next loop
2019/02/28 18:42:30 select struct: get quit signal, now prepare to jump out of the loop
2019/02/28 18:42:30 have jump out of the loop
break 语句可以结束 for、switch 和 select 的代码块。break 语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的 for、switch 和 select 的代码块上。
goto label
func test(quitChan chan bool) {
var (
interValTime = 4
sleepTime = 1
)
for {
select {
case <-time.After(time.Duration(interValTime) * time.Second):
log.Printf("select struct: get time chan every %v second interval\n", interValTime)
case <-quitChan:
log.Println("select struct: get quit signal, now prepare to jump out of the loop")
goto forEnd
}
log.Printf("for struct: sleep %v second before start next loop\n", sleepTime)
time.Sleep(time.Duration(sleepTime) * time.Second)
}
forEnd:
log.Println("have jump out of the loop")
}
2019/02/28 18:47:52 select struct: get time chan every 4 second interval
2019/02/28 18:47:52 for struct: sleep 1 second before start next loop
2019/02/28 18:47:57 select struct: get time chan every 4 second interval
2019/02/28 18:47:57 for struct: sleep 1 second before start next loop
2019/02/28 18:47:58 select struct: get quit signal, now prepare to jump out of the loop
2019/02/28 18:47:58 have jump out of the loop
goto 跳到标签指定的代码块处
return
func test(quitChan chan bool) {
var (
interValTime = 4
sleepTime = 1
)
func() {
for {
select {
case <-time.After(time.Duration(interValTime) * time.Second):
log.Printf("select struct: get time chan every %v second interval\n", interValTime)
case <-quitChan:
log.Println("select struct: get quit signal, now prepare to jump out of the loop")
return
}
log.Printf("for struct: sleep %v second before start next loop\n", sleepTime)
time.Sleep(time.Duration(sleepTime) * time.Second)
}
}()
log.Println("have jump out of the loop")
}
2019/02/28 18:54:31 select struct: get time chan every 4 second interval
2019/02/28 18:54:31 for struct: sleep 1 second before start next loop
2019/02/28 18:54:36 select struct: get time chan every 4 second interval
2019/02/28 18:54:36 for struct: sleep 1 second before start next loop
2019/02/28 18:54:37 select struct: get quit signal, now prepare to jump out of the loop
2019/02/28 18:54:37 have jump out of the loop
return 跳出当前函数