AI智能
改变未来

Go语言可能会遇到的坑


Go语言可能会遇到的坑

点击蓝字关注 

阅读本文大约需要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】加小助手索取。

点击下面进入送书活动传送门:

送书、四本实体书籍 & 免费csdn下载

本文由“壹伴编辑器”提供技术支持

本公众号免费提供csdn下载服务,海量IT学习资源,如果你准备入IT坑,励志成为优秀的程序猿,那么这些资源很适合你,包括但不限于java、go、python、springcloud、elk、嵌入式 、大数据、面试资料、前端 等资源。同时我们组建了一个技术交流群,里面有很多大佬,会不定时分享技术文章,如果你想来一起学习提高,可以公众号后台回复【2】,免费邀请加技术交流群互相学习提高,会不定期分享编程IT相关资源。

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Go语言可能会遇到的坑