golangのinterface{}の不思議
golangを触り始めて約3ヶ月
interface{}が便利なのでよく使います
ただ最初はinterface{}の挙動がよくわかってなくて使うたびに苦戦してたのでメモメモ_φ(・_・
package main import( "fmt" ) func main() { Output("string") Output(100) Output(true) } func Output(x interface{}) { fmt.Println(x) } => string 100 true
特に型を宣言しなくてもなんでもこーい!なことができる
すごい便利
ただ, もし受け取った関数で型がしっかりと指定しないとダメなケースがある
大体がこのパターン, だから便利だけとメンドくささもある
例えば次のような場合
package main import( "fmt" ) func main() { Output(100) } func Output(x interface{}) { fmt.Println(x*2) } => # command-line-arguments ./test.go:12:16: invalid operation: x * 2 (mismatched types interface {} and int)
interface{}型とint型では計算できませんよって怒られます
なんでも受け取ってくれるのに実は繊細なのかなって感じです
解決作
package main import( "fmt" ) func main() { Output(100) } func Output(x interface{}) { fmt.Println(x.(int)*2) } => 200
変数の後ろにx.(int)と, interface{}型で受け取ったけど, この子はint型ですよーって書いてあげれば大丈夫
主にswitchを使って分岐処理をさせることが多いです
package main import( "fmt" ) func main() { Output("aaaaaaa") Output(100) Output([]string{"a", "b", "c"}) } func Output(x interface{}) { switch v := x.(type) { case string: fmt.Println(v) case int: fmt.Println(2*v) case []string: fmt.Println(v) } } => aaaaaaa 200 [a b c]
こんな感じで変数の型(type)によって処理を分岐させます
あともう1つ詰まったところがあり, それが
[]interface{}ってやっとけば, stringだろうがintだろうがboolだろうがうけとってくれるやろーって
package main import( "fmt" ) func main() { Output([]string{"a", "b", "c"}) Output([]int{100, 200, 300}) Output([]bool{true, false}) } func Output(x interface{}) { switch v := x.(type) { case []interface{}: fmt.Println(v) default: fmt.Println("ハズレ") } } => ハズレ ハズレ ハズレ
そうはうまくいかないんですね
見事にスルーされてます(泣
実は[]interface{}型の配列であれば受け取ってもらえます
package main import( "fmt" ) func main() { Output([]interface{}{"test1", 100, true}) } func Output(x interface{}) { switch v := x.(type) { case []interface{}: fmt.Println(v) default: fmt.Println("ハズレ") } } => [test1 100 true]
interface{}型の配列が存在するために, 配列の型なんでもこーいって形で使用することができないのかなって感じです
というな感じで, interface{}と戯れてましたってお話でした
interface{}は便利