Go's Slice Tricks

December 28, 2018
Go

感慨

自学之路,其实就是递归式踩坑之路。

要是有人带能少踩坑就好了(葛优躺

这篇文章也是拖了好久了,趁着这阵子有点空,记下来吧。

缘起

写的代码,数据怎样保存?

在 冯诺依曼 体系架构中,代码和数据都是保存在计算机内存之中。。。。咳咳咳,扯远了

所以写程序需要考虑数据在内存之中的形式。一般在 CPP 里头也就偷懒用 Vector 了;C 那基本就只能自己造轮子纯手撸;Java 也是有自带的库,那 Go 呢?

肯定有啦,但是我在查这类东西的时候,发现了这个 SliceTricks

也就是说,Go 虽然也如 C++/Java 提供了自带的库,但是它的 Slice 应该是一个不错的解决方案吧(猜测中。。

那么就试一试吧。

函数之间。。。

这个我已经在 GitHub 中提到了

按照官方 Tour (Slices are like references to arrays) 中的这个说法,Slice 是 array 的一个引用。

如果是引用的话,那么我就可以以其为参数,在 function call 之中 pass 给目标函数,从而不用返回,就可以在目标函数中修改对应的值。以此避免对于计算机来说的昂贵的 copy 操作。

嗯,的确,没问题。你确实可以修改。

但是当你尝试改变容量的时候,奇迹发生了。

slice = append(slice,make(type,1)...)

发起调用的函数在 function call 结束之后,发现 Slice 并没有被更改。

WTF??!!

缘由

看这里

append 在操作的时候,重新造了个 array,然后把这个 Slice 指向了新 array。。。。

行吧。

还是扩容

如果在一个函数中先扩容:

slice = append(slice,make(type,1)...) //注意这里的数字是 1

再在接下来的函数中给刚扩容的那个赋值:

slice[cap(slice)-1] = someElement

你会惊奇地发现,大多数时候会炸,原因是越界。加个断点跟进去,会发现在上述那行产生问题。

加个 cap(slice) 的 watcher。嗯?你在逗我?

换成 len() 就不会有问题。

文档里 有这么一句

The append function appends the elements x to the end of the slice s, and grows the slice if a greater capacity is needed.

左思右想,这货增加 slice 的 capacity 就是随性完全不走心啊。。

行吧,那就这样吧。

Digging Into Go Routines

April 16, 2019
Go

尝试构建简易 Event Bus

April 12, 2019
Go

Golang 的 GOPATH

November 25, 2018
Go
comments powered by Disqus.
Can't load? Check your connectivity and try again.