Go 语言中Select与for结合使用时可能会遇到的坑

u010511236 · 2015-11-13 15:00:00 · 20919 次点击 · 预计阅读时间 1 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2015-11-13 15:00:00 的文章,其中的信息可能已经有所发展或是发生改变。

  作为一个刚接触go编程的新鸟,是不是被它的某些新特性给吓到,尤其是之前已经习惯了C++的编程。对于Go语言,网上褒贬不一,有极力推崇的,如七牛的许式伟,其对go的评价极高,并预言Go的市场占有率会一直逐步上升,取代java,成为第一。也有极力贬低的,他们一般会网络上有各种博客帖子,详细的剖析了go的不妥之处。而我接触go这段时间之后,不得不说,它真的是一门很有意思的语言,为什么用有意思形容呢,借用一句装逼的话,存在即合理。go能够慢慢被国内国外的各大互联网公司用于服务器架构,它自有它的闪光之处,而至于有意思呢,就需要对它有兴趣的人慢慢去发现,(呃。。。。这个情景导入有点长,貌似有点跑偏)

  好,言归正传,最近在用go开发项目的过程中突然发现一个坑,尤其是对于其它传统语言转来的人来说一不住注意就掉坑里了,话不多说,show you the code。

func test(){
    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: ")
    }
}
执行后发现,什么?居然break不出去?后来查了一下资料发现,当for 和 select结合使用时,break语言是无法跳出for之外的,因此若要break出来,这里需要加一个标签,使用goto, 或者break 到具体的位置

解决方法一:使用golang中break的特性,在外层for加一个标签

func test(){
	i := 0
	ForEnd:
	for {
		select {
		case <-time.After(time.Second * time.Duration(2)):
			i++
			if i == 5{
				fmt.Println("break now")
				break ForEnd
			}
			fmt.Println("inside the select: ")
		}
		fmt.Println("inside the for: ")
	}
}

解决方法二: 使用goto直接跳出循环

func test(){
	i := 0

	for {
		select {
		case <-time.After(time.Second * time.Duration(2)):
			i++
			if i == 5{
				fmt.Println("break now")
				goto ForEnd
			}
			fmt.Println("inside the select: ")
		}
		fmt.Println("inside the for: ")
	}
	ForEnd:
}

如上,成功从坑中走出。



版权声明:本文为博主原创文章,未经博主允许不得转载。


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

本文来自:CSDN博客

感谢作者:u010511236

查看原文:Go 语言中Select与for结合使用时可能会遇到的坑

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

20919 次点击  ∙  1 赞  
加入收藏 微博
7 回复  |  直到 2019-08-16 15:35:34
victorl
victorl · #1 · 9年之前

golang中select 本身就是一个循环,只有case条件成立时才跳出select循环。所以你加了个break就是显示的调用跳出当前select的循环

lcplj123
lcplj123 · #2 · 9年之前

我不知道select本身是不是循环,但是此处的break语句的作用就是让当前的select语句结束执行而已,由于外层有一个for循环,所以流程很快又会被select掌控。确实,通过break tag; 能解决这个问题。

gvforjob
gvforjob · #3 · 9年之前
lcplj123lcplj123 #2 回复

我不知道select本身是不是循环,但是此处的break语句的作用就是让当前的select语句结束执行而已,由于外层有一个for循环,所以流程很快又会被select掌控。确实,通过break tag; 能解决这个问题。

select 就好像 switch 一样,break 都是跳出当前的 switch,没啥好奇怪的

chuqq
chuqq · #4 · 9年之前
gvforjobgvforjob #3 回复

#2楼 @lcplj123 select 就好像 switch 一样,break 都是跳出当前的 switch,没啥好奇怪的

同意

qkb_75_go
qkb_75_go · #5 · 9年之前

这也算坑, 这样的坑要一百个也有, 请看下面这个简单的 两重 for 循环, 同样 break 也跳不出去: for { for { if ....... break } }

呵呵, 有意思么??

hades2013
hades2013 · #6 · 7年之前

学习,,mark

coldwarm7
coldwarm7 · #7 · 6年之前

直接return

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