用python写业务代码有三四年了,忽然切换用golang写业务的时候会遇到一些奇怪的问题。这些问题不能说golang的坑,只能说自己对于go的认知还不够清晰。


我的实际场景是这样的,我从redis取出任务后,经过各种的数据会扔给Elasticsearch,原始的数据会扔给Mysql里面。但中间遇到一个问题,我在函数里扩展了原始数据,但是在另一个函数里收到了影响。 后来通过输出对象内存地址来分析出问题的。 

第一个问题是,我从main里面创建的一个slice列表,并传递给func函数,但是这函数会针对该slice切片进行修改。 一个slice从main()到func()里是一个copy地址的过程。

如果你想在func里修改slice内容,又不想让外层的slice收到影响。 可以使用copy(dst,src)。

第二个问题是,我在func里面针对slice进行append添加数据,但是在main()里看不到append的数据。 后来查询了相关的文档,我们需要使用指针地址的。 

该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新。

http://xiaorui.cc/2016/03/05/%E4%BD%BF%E7%94%A8golang%E4%BC%A0%E9%80%92%E5%8F%98%E9%87%8F%E7%BB%99%E5%87%BD%E6%95%B0%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/

golang slice的copy函数用法:


我们通过下面的例子深究下slice append的问题,测试代码运行后得到的print内存地址是不一样的。 执行了append操作后,内存地址发生了变化,说明已经不是引用传递。

Slice是引用类型,里面的所有记录指向的都是内存中的同一块内存区。我们来说下Slice的处理机制,当Slice的容量还有空闲的时候,append进来的元素会直接使用空闲的容量空间,但是一旦append进来的元素个数超过了原来指定容量值的时候,内存管理器就是重新开辟一个更大的内存空间,用于存储多出来的元素,并且会将原来的元素复制一份,放到这块新开辟的内存空间。

下面是完整的测试实例.

下面是测试的结果.

一般来说 string 、int … 是值传递。  array、slice、map是引用传递。  既然golang设计到这么简洁了,搞不懂为什么不针对这些细节再封装下。



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!
暂无相关产品

发表评论