golang における interface 型とは
var v interface{}
ゼロ個のメソッドを指定されたインターフェース型は、 空のインターフェース と呼ばれます:
空のインターフェースは、任意の型の値を保持できます。 (全ての型は、少なくともゼロ個のメソッドを実装しています。)
だそう。
ゼロ個のメソッド辺りがちょっとよく分からない。
型変換
interface{} 型はどんな値でも代入できる。
けど、型が定まってないので、代入は簡単だけど、扱うには少し大変。
interface{} → 任意の型
package main
import (
"fmt"
)
func main() {
var v interface{} = "もじ"
// var v interface{} = false
// var v interface{} = 0
// 変換
conv, ok := v.(string)
// conv, ok := v.(bool)
// conv, ok := v.(int)
if !ok {
fmt.Print("変換に失敗しました\n")
return
}
fmt.Printf("型: %T, 値: %v\n", conv, conv)
}
interface{} → 構造体(struct)
やることはさほど変わらない。
package main
import (
"fmt"
)
type Test struct {
Name string
}
func main() {
var v interface{} = Test{
Name: "太郎",
}
// var v2 interface{} = &Test{
// Name: "太郎",
//}
conv, ok := v.(Test)
// conv, ok := v.(*Test)
if !ok {
fmt.Print("ERROR\n")
return
}
fmt.Printf("%t, %v\n", conv, conv)
}
switch 文限定
switch 文で xxxx.(type) を使用して、
型を調べることもできる。
使い所がちょっと分からない。
package main
import (
"fmt"
)
type Test struct {
Name string
}
func main() {
var v interface{} = "もじ"
// var v interface{} = false
// var v interface{} = 0
// var v interface{} = Test{
// Name: "太郎",
// }
switch v.(type) {
case string:
fmt.Print("i is string.\n")
case bool:
fmt.Print("i is bool.\n")
case int:
fmt.Print("i is int.\n")
case int64:
fmt.Print("i is int64.\n")
case Test:
fmt.Print("s is Test.\n")
default:
}
}
interface{} は型変換してから扱った方がいい
interface{} の仕様がよく分からない。
型は代入されたものでなんとなく判断してるぽい。
interface{} は非常に曖昧な印象を受けるので、
型変換してから扱うべきと思う。
下記、雑に interface{} について調べたコード。
package main
import (
"fmt"
)
func test(v string) {
fmt.Print(v, "\n")
}
func main() {
// v には string が入ってるぽい
var v interface{} = "もじ"
var str string = "もじ"
fmt.Print((v == str), "\n")// true
var i int = 0
var i2 int64 = 0
// 当たり前だけどこちらは型が違うという旨のエラーが出る。
fmt.Print((i == i2), "\n")
// invalid operation: i == i2 (mismatched types int and int64)
// i3 には int が入ってるぽい
var i3 interface{} = 0
fmt.Print((i3 == i), "\n")// true
fmt.Print((i3 == i2), "\n")// false。エラーは出ない
// 関数の引数として使うと、interface 型は string 型として扱えない。
// まず v の型をはっきりさせて。という旨のエラーが出る
//
test(v)
// cannot use v (variable of type interface{}) as string value in argument to test: need type assertion
}