Go append 的小技巧
在开发的过程中,遇到了一个需要将 T 类型切片映射为 F 类型切片的操作,由于 Go 的标准库中并没有内置 Map 函数,于是就写了一个简单的辅助函数。
第一版是这样的
1 |
|
先使用 make 初始化了一个长度和容量为 len(ts) 的切片,然后通过 rang ts 获取每个元素对应的索引以及值,然后将它赋予给对应索引的 result。
到目前为止,这个函数以及满足我的目标了,但是我觉得也可以通过 append 函数来实现。
在 Go 中,append 做为一个内置函数,作用是向切片的尾部追加元素,并返回新的切片。同时在追加的过程中如果发现切片的容量不够时,就会对切片的底层数组进行扩容。
于是我修改了一下代码,得到一个新的版本
1 |
|
完成后,当我再跑一次测试时发现结果并不是我想要的,此时的 result 变成了 [0 0 1 2] , 而不是我想要的 [1 2]。
仔细审视了一下代码,发现问题出在初始化 result 时 make 的调用上。在使用 make 初始化 result 时,我只传入了一个 IntegerType 的参数,即 len(ts)。在这种情况下,make 会返回一个长度与容量相同的切片。
注意,问题就出在长度与容量相同,此时 make 返回给我的是一个具有长度的切片,并且其中的元素都被赋予了零值。因此当我调用 append 往 result 上追加数据时,就会因为容量不足,首先扩容一次,然后再追加新的元素。于是结果就变成了 [0 0 1 2]。
因此,我需要先初始化一个长度为 0 的切片,然后从一个空切片开始追加元素,这样就可以达到我的目标了。代码就变成如下了
1 |
|
总结一下,在使用 make 初始化一个切片时,需要考虑是否指定切片的长度,并且长度是否会对接下来的操作造成影响。除此之外, append 的操作操作位置就是切片的长度所对应的位置。