「なんかのスライス」を「interface{}
のスライス」にしたい。
スライスでなければ、「なんか」を「interface{}
」にするのは単に抽象度の増すキャストなので超簡単なわけだけど。
s := "hoge" i := interface{}(s)
これがスライスとなるとだめ
ss := []string{"aaa","bbb"} si := []interface{}(ss)
cannot convert ss (type string) to type interface {}
あ、ハイ
理由
- [go-nuts] How to convert some structs slice to []interface{}? - Grokbase
- Frequently Asked Questions (FAQ) - The Go Programming Language
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{}:
"なんかの"スライスを受けてinterfaceのスライスにしたい
- 特定のtypeのスライスが来るのであれば、ループ回せばよい
- "なんかの"スライスが来るのをinterfaceのスライスにするには、やっぱりループが必要
- しかし
[]T
を[]interface{}
で受けることはできないのだから、rangeかけれる保証が必要 - アサーションするしかないっぽい?
- しかもrangeかけれる保証がある中でやらなきゃいけないっぽい?
ということでこうなった
http://play.golang.org/p/ao3gq2VHFn
package main import "fmt" import "reflect" func AbstractSlice(arr interface{}) []interface{} { dest := []interface{}{} switch sl := arr.(type) { case []interface{}: // こういうのは無理なんですよ case string: // rangeかけるためにcase内じゃないとダメ for _, b := range sl { dest = append(dest, b) } case []string: for _, str := range sl { dest = append(dest, str) } case []int: for _, i := range sl { dest = append(dest, i) } } return dest } func main() { a := "slice of byte" fmt.Println( reflect.TypeOf(a), reflect.TypeOf(AbstractSlice(a)), ) b := []string{"Hello", "interface"} fmt.Println( reflect.TypeOf(b), reflect.TypeOf(AbstractSlice(b)), ) c := []int{2, 3, 4, 5} fmt.Println( reflect.TypeOf(c), reflect.TypeOf(AbstractSlice(c)), ) }
う〜ん...
DRYな備忘録として