go语言的一些陷阱

作者: lazypos | 来源:发表于2017-11-09 12:20 被阅读206次

        虽然go语言使用起来方便简单,但他有很多特性是比较与众不同的,在不了解的情况下,编码时候就会产生很多莫名其妙的bug。

channel

channel示例代码

        这里的channel默认是无缓冲的,但是有三个线程往里面写,而函数返回的时候只从中读取了一个,根据channel的特性,另外两个线程(go routine 个人别称 线程)中,另外两个线程会一直阻塞在ch <- true 这一行,造成资源泄漏(内存涨)。

解决办法

        有两个解决办法,第一种使用select加上default的办法,这样,当channel无法写入的时候,就会触发default退出。

换成select和default

        另一个办法是创建channel的时候,容量足够大,大于等于3,使得写入不阻塞。

创建管道指定容量大小

go routine

示例代码

        以为会输出1,2,3 实际却输出了3,3,3,原因是V这个变量是同一个地址重复使用,三次循环 &V 的地址都是一样的,只是V的值改变了,而GetId()函数的调用是用指针是调用的,所以船体给go routine的是V的地址,三次都一样。然而go routine是异步开启的,循环执行太快导致三个go routine得到的该地址值是最后一个了

解决办法

        如果在gov.GetId() 之后加上足够时间的sleep()让该 routine 建立起来,则可以避免这样的问题。

加上sleep确保线程开启

        或者先用一个临时变量存储v的值,再用临时变量开启routine

使用临时变量

range

示例代码

        原本以为在 循环刚开始的时候,把arr[1]的值改成10后,第二次循环的时候v会输出 10,结果arr[1]的值确实是改了,而 v 依旧输出是20。

        原因是如果是数组等非指针类型,会在循环前复制一份,循环的时候使用的是复制的值。(channel/map/slice/指针数组等不会这样)

解决办法

        尽量使用指针数组或者切片(slice)。

创建的时候是切片 循环的时候转成切片

slice

示例代码

        同样是去掉第二个元素,用函数的方式却跟预料的不一样。

        原因:实际上,切片作为参数的时候,虽然内容是指针,切片本身是拷贝,就是说函数内外 &arr 的地址不一样,但 &arr[n] 里面的元素的地址是一样的, 所以函数外的arr长度并没有减少。

解决办法

        使用返回值重新赋值的方式。

返回切片

相关文章

  • go语言陷阱之二:Unused Variables

    继续来控go语言的陷阱,今天来一发go语言中未使用变量的陷阱,不使用就扔掉嘛,go语言发明人如是说...先来看坑:...

  • go语言的一些陷阱

    虽然go语言使用起来方便简单,但他有很多特性是比较与众不同的,在不了解的情况下,编码时候就会产生很多莫名其...

  • golang 新手要注意的陷阱和常见错误

    Golang 新手要注意的陷阱和常见错误 Go是一门简单有趣的语言,但与其他语言类似,它会有一些技巧。。。这些技巧...

  • go语言陷阱之三:Unused Imports

    继续go语言的陷阱,今天的坑是未使用的go语言包,先看错误代码: 导入了这三个包,但是都没有用到,在go语言中,这...

  • 关于go语言的几个陷阱

    原文 https://github.com/googege/blog/ 关于go语言的几个陷阱,以及我们应该注意的...

  • go语言——数据运算陷阱

    go语言规定不允许在整数型变量和浮点型变量之间进行任何数学运算。错误例子如下: 改正结果如下:

  • go语言学习-从基础到实战到源码分析

    收集的一些go语言学习资料,有go基础学习系列,go项目实战,go进阶-go源码分析,还有go的一些书籍,go的架...

  • Linux搭建golang开发环境

    go语言最近是比较火的,go语言是很不错的一门语言。所以最近就把一些基础的东西写出来,随后也会也一些go的算法和设...

  • 潍坊go语言培训

    潍坊go语言培训潍坊go语言培训潍坊go语言培训潍坊go语言培训潍坊go语言培训潍坊go语言培训潍坊go语言培训潍...

  • 从基本结构了解GO语言设计及思想

    学习GO语言,我们可以通过其基本结构,来学习GO语言的一些设计和思想。通过本质去了解GO语言的设计及思想,这样对G...

网友评论

  • e3cadb176d00:第一个channel 是无缓冲的,并不是容量为1,容量为1 的叫有缓冲的channel,概念上不同,效果也不同的
    lazypos::smirk: 多谢指正

本文标题:go语言的一些陷阱

本文链接:https://www.haomeiwen.com/subject/drjpmxtx.html