专栏首页我的小碗汤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】加小助手索取

本文分享自微信公众号 - 我的小碗汤(mysmallsoup),作者:小碗汤

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-09-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Web应用测试最佳工具Burp Suite

    Burp Suite是Web应用程序测试的最佳工具之一,可以对请求的数据包进行拦截和修改,扫描常见的web安全漏洞,暴力破解登录表单、遍历数据等等。

    我的小碗汤
  • 用go语言爬取珍爱网 | 第二回

    昨天我们一起爬取珍爱网首页,拿到了城市列表页面,接下来在返回体城市列表中提取城市和url,即下图中的a标签里的href的值和innerText值。

    我的小碗汤
  • 日志文件转储压缩实现

    日志的转储和压缩是非常关键的,它不仅可以减少硬盘空间占用,主要还可以在发生故障时根据日志定位出故障原因。下面来看看golang和java的文件转储实现。

    我的小碗汤
  • 点云表面法向量的估计

    点云表面法向量是一种重要几何表面特性,在计算机图像学中有很广的应用,例如在进行光照渲染和其他可视化效果时确定一个合理的光源位置。

    点云PCL博主
  • 洛谷P2870 [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold

    题目描述 FJ is about to take his N (1 ≤ N ≤ 30,000) cows to the annual"Farmer of the...

    attack
  • HDU 6016 Count the Sheep

    Count the Sheep Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/6...

    ShenduCC
  • pta 习题集 5-5 最长连续递增子序列 (dp)

    Count the Sheep Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/6...

    ShenduCC
  • 马云清华EMBA演讲:一个人要成功靠情商 要不败靠智商

    大数据文摘
  • maven:命令行执行junit 测试示例

    有时我们希望在命令行执行JUNIT测试,该怎么做呢? 举例说明吧,如下我要在命令行执行common-base2项目下的junit 测试类NetworkTest...

    用户1148648
  • P2880 [USACO07JAN]平衡的阵容Balanced Lineup

    题目背景 题目描述: 每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John 决定让一些牛们玩一场飞盘比赛....

    attack

扫码关注云+社区

领取腾讯云代金券