点击蓝字关注 ??
阅读本文大约需要3分钟。
最近在用go开发项目的过程中突然发现一个坑,尤其是对于其它传统语言转来的人来说一不注意就掉坑里了,话不多说,咱看代码:
1//writeToCSV
2func writeESDateToCSV(totalValues chan []string) {
3 f, err := os.Create("t_data_from_es.csv")
4 defer f.Close()
5 if err != nil {
6 panic(err)
7 }
8
9 w := csv.NewWriter(f)
10 w.Write(columns)
11
12 for {
13 select {
14 case row := <- totalValues:
15 //fmt.Printf("Write Count:%d log:%s\n",i, row)
16 w.Write(row)
17 case <- isSendEnd:
18 if len(totalValues) == 0 {
19 fmt.Println("------------------Write End-----------------")
20 break
21 }
22 }
23 }
24
25 w.Flush()
26 fmt.Println("-------------------------处理完毕-------------------------")
27 isWriteEnd <- true
28}
当数据发送完毕,即isSendEnd不阻塞,且totalValues里没数据时,跳出for循环,这里用了break。但是调试的时候发现,程序阻塞在了14行,即两个channel都阻塞了。然后才惊觉这里break不是这么玩,然后写了个测试方法测试一下:
package main
import (
"time"
"fmt"
)
func main() {
i := 0
for {
select {
case <-time.After(time.Second * time.Duration(2)):
i++
if i == 5{
fmt.Println("break now")
break
}
fmt.Println("inside the select: ")
}
fmt.Println("inside the for: ")
}
fmt.Println("outside the for: ")
}
运行输出如下结果,break now之后还是会继续无限循环,不会跳出for循环,只是跳出了一次select
inside the select:
inside the for:
inside the select:
inside the for:
inside the select:
inside the for:
inside the select:
inside the for:
break now
inside the for:
inside the select:
inside the for:
inside the select:
inside the for:
inside the select:
inside the for:
若要break出来,这里需要加一个标签,使用goto, 或者break 到具体的位置。
解决方法一:
使用golang中break的特性,在外层for加一个标签:
package main
import (
"time"
"fmt"
)
func main() {
i := 0
endLoop:
for {
select {
case <-time.After(time.Second * time.Duration(2)):
i++
if i == 5{
fmt.Println("break now")
break endLoop
}
fmt.Println("inside the select: ")
}
fmt.Println("inside the for: ")
}
fmt.Println("outside the for: ")
}
解决方法二:
使用goto直接跳出循环:
package main
import (
"time"
"fmt"
)
func main() {
i := 0
for {
select {
case <-time.After(time.Second * time.Duration(2)):
i++
if i == 5{
fmt.Println("break now")
goto endLoop
}
fmt.Println("inside the select: ")
}
fmt.Println("inside the for: ")
}
endLoop:
fmt.Println("outside the for: ")
}
两程序运行输出如下:
inside the select:
inside the for:
inside the select:
inside the for:
inside the select:
inside the for:
inside the select:
inside the for:
break now
outside the for:
Process finished with exit code 0
综上可以得出:go语言的switch-case和select-case都是不需要break的,但是加上break也只是跳出本次switch或select,并不会跳出for循环。
go、docker、k8s等学习资源,可在文末公众号后台回复【1】加小助手索取