Go言語で配列を結合したくなることってあると思う。
最初に書いたのはこんな関数だった。
func concat(xs, ys []int) []int {
zs := make([]int, len(xs) + len(ys))
for i, x := range xs {
zs[i] = x
}
l := len(xs)
for j, y := range ys {
zs[l + j] = y
}
return zs
}
これだとint
型のスライスにしか対応できなくて、例えばstring
型のスライスを結合したい、ってなったときは似たような関数を何個も書かなくちゃいけない。
それをどうにかするために空interfaceを使う、って手も無いわけじゃないけど、そうするとキャストが……。
そんなときにジェネリクスを(まだ)持たないGo言語でも型安全性を保ったまま配列を結合できる方法があったのでメモ。
concat_slice.go
package main
import "fmt"
func main() {
xs := []int{1,2,3}
ys := []int{4,5,6}
//ここで結合
zs := append(xs, ys...)
fmt.Println(zs)
}
ちなみに、append(xs, ys...)
の...
というのは、可変長の引数を配列で渡すときに使うもの。
例えば、
func sum(xs ...int) (s int) {
for _, x := range xs {
s += x
}
return
}
という関数があったとき、通常は、
sum(1, 2, 3, 4, 5) //=> 15
として呼び出すけれど、...
を配列のあとにつけると、
xs := []int{1, 2, 3, 4, 5}
sum(xs...)
こういう風にスライスを可変長引数として渡すことが出来る。
で、append
も可変長引数を受け取る組み込み関数だったので行けるかな、と思ったら案の定いけた、という感じ。
気付かなかっただけで、builtinパッケージのappend
の説明にも書いてあった模様。