分享
  1. 首页
  2. 文章

Go语言可能会遇到的坑

aside section ._1OhGeD · · 1394 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

最近在用go开发项目的过程中突然发现一个坑,尤其是对于其它传统语言转来的人来说一不注意就掉坑里了,话不多说,咱看代码:

//writeToCSV
func writeESDateToCSV(totalValues chan []string) {
 f, err := os.Create("t_data_from_es.csv")
 defer f.Close()
 if err != nil {
 panic(err)
 }
 w := csv.NewWriter(f)
 w.Write(columns)
 for {
 select {
 case row := <- totalValues:
 //fmt.Printf("Write Count:%d log:%s\n",i, row)
 w.Write(row)
 case <- isSendEnd:
 if len(totalValues) == 0 {
 fmt.Println("------------------Write End-----------------")
 break
 }
 }
 }
 w.Flush()
 fmt.Println("-------------------------处理完毕-------------------------")
 isWriteEnd <- true
}

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


扫码关注,精彩内容第一时间推给你

image

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:aside section ._1OhGeD

查看原文:Go语言可能会遇到的坑

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1394 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏