可変長引数をそのまま…interface{}に渡せるか? - Can I convert a []T to an []interface{}?

Ken published on
2 min, 373 words

Categories: Programming

Tags: golang

Golangで []T[]interface{} に変換しなければならないのだろうか?という疑問があった。

具体的には次のようなコードの場合。

▶The Go Playground http://play.golang.org/p/Gg2NTEQFBX

package main

import "fmt"

func main() {
	fmt.Println("Hello, playground")
	A("a", "b", "c", "d", "e")	// [a b c d e] ... Not the expected value.
	AA("a", "b", "c", "d", "e")	// OK ... the expected value.
}

func A(text ...string) {
//	B(text...)	// prog.go:12: cannot use text (type []string) as type []interface {} in argument to B
	B(text)
}

func AA(text ...string) {
	ss := make([]interface{}, len(text))
	for i, s := range text {
		ss[i] = s
	}
	B(ss...)
}

func B(values ...interface{}) {
	for _, value := range values {
		fmt.Println(value)
	}
}

Aメソッドに可変長引数を渡した場合、さらに別のメソッドの引数がinterface{}の可変長引数ならそのままいけるかな?と思ったらいけなかった。
AAメソッドのように詰め直してあげれば問題ないことはわかっているんだけど、もっとシンプルにスマートな方法ってないのだろうか?という疑問があった。

調べてみるとこんなところにまんま載っていた!

▶Frequently Asked Questions (FAQ) - The Go Programming Language
https://golang.org/doc/faq#convert_slice_of_interface

Can I convert a []T to an []interface{}?

Not directly, because they do not have the same representation in memory. It is necessary to copy the elements individually to the destination slice. This example converts a slice of int to a slice of interface{}:

t := []int{1, 2, 3, 4}
s := make([]interface{}, len(t))
for i, v := range t {
    s[i] = v
}

やっぱり、こうしろということらしい。