golang
では、interface{}
型に対して型アサーションを行うことで、そのインターフェースが特定の型であると仮定して、その型のメソッドを操作することができます。
var i interface{} = "hello"
s := i.(string)
fmt.Println(s)
このコードは、元々のinterface{}
を文字列にアサーションします。
ただし、注意しなければならないのは、この型が文字列でない場合、このコードは直接パニックを引き起こします。
args := []interface{}{
1,
"1",
"2",
}
for _, arg := args {
val := arg.(int) // interface conversion: interface {} is string, not int
fmt.Println(val)
}
golangは、型アサーションが2つの値を返すメカニズムを提供しており、1つは変換後の値で、もう1つはアサーションが正しいかどうかです。
args := []interface{}{
1,
"1",
"2",
}
for _, arg := args {
if val, ok := arg.(int); ok {
fmt.Println(val)
} else {
fmt.Println("not int.")
}
}
ここで注意する必要があるのは、
- 第2の戻り値がない場合、型が確定していない限り、アサーションの失敗によりパニックが発生する可能性があることです。
- 第2の戻り値を追加すると、パニックは発生しません。
少し手間がかかるかもしれませんが、常に型変換を行う方が安全です。
また、注意しなければならない点は、アサーションが失敗した場合のval
は、アサーションした型のゼロ値になるということです。
アサーションが失敗した場合のval
は、アサーションした型のゼロ値になります。
for _, arg := range args {
if val, ok := arg.(int); ok {
fmt.Println(val, ok) // 1, true
} else {
fmt.Println(val, ok) // 0 , false
// 0, false
}
}
一般的に、アサーションが失敗した後、この値を使用することはあまりありませんが、うっかりするとトラップにはまることがあります。