07 August 2014
合并slice,被copy虐了一通,后来才发现,append能虐copy几条街。

合并slice,跟合并数组一样,是比较常见的操作。映像中C++运算符重载以后,直接用加号就可以了。Golang果断不行。先开始用copy解决。

func copy(dst, src []Type) int

从来没用过这个函数,返回值和append还不一样,返回的是复制的数目。而且只能针对slice操作,不支持其他类型。能参数表也能看出,两个参数必须是同一种类型,不可以是[]Type[]interface{}这种形式。此函数也不是追加到dst后面,而是从头开始复制。如果要追加到后面,还需要指出位置信息。copy实现的合并数组完整代码:

a := []int{1, 2, 3, 4}
b := []int{5, 6, 7}
c := make([]int, len(a)+len(b))
copy(c, a)
copy(c[len(a):], b)

copy的过程中,如果dst空间不足,是不会自动追加空间的。所以,合并之前要申请一个足够的空间。接着就是复制两次。第二次复制还需要指出slice位置,防止被覆盖。

这个代码虽然功能上没问题,但是总觉得比较脏。后来无意中发现,append函数的参数是支持变长参数类型的。

func append(slice []Type, elems ...Type) []Type

这样,三行复杂的代码变成了一行:

a := []int{1, 2, 3, 4}
b := []int{5, 6, 7}
d := append(a, b...)

参考结果:

0xfeee1f74
0xfeee1f38
[1 2 3 4 5 6 7]
0xfeee1f2c
[1 2 3 4 5 6 7]
0xfeee1f20
[5]

本文所涉及到的完整源码请参考


最近在看Effective Go,觉得不错,推荐给大家。


参考文献

原文链接:Golang——append的可变参数,转载请注明来源!

EOF