首先
首先类型assertion和类型switch只能作用于interface{},不能是其他类型。
func main() {
var v string = "hello" // var v interface{} = “hello"
s, ok := v.(string)
fmt.Println("s=",s,",ok=",ok)
switch v.(type) {
case string:
fmt.Println("This is a string");
case int:
fmt.Println("This is a int");
default:
fmt.Println("This is default");
}
}
得到如下编译错误:
$ go build
# main
./main.go:XX: invalid type assertion: v.(string) (non-interface type string on left)
./main.go:XX: cannot type switch on non-interface value v (type string)
类型assertion
语法
element.(T)
例子
package main
import "fmt"
func main() {
var i interface{} = "hello"
s := i.(string)
fmt.Println(s)
f := i.(float64) // panic
fmt.Println(f)
}
运行结果:
hello
panic: interface conversion: interface {} is string, not float64
goroutine 1 [running]:
main.main()
/$GOPATH/src/main/main.go:11 +0x192
- 从i到string的类型assertion成功,返回s等于"hello"。
- 从i到float64的类型assertion失败,因为i不是一个float64类型,导致panic。
当然assertion失败没关系,但是不能panic呀,解决方法是:
package main
import "fmt"
func main() {
var i interface{} = "hello"
s := i.(string)
fmt.Println(s)
f, ok := i.(float64) // panic
if ok {
fmt.Println(f)
} else {
fmt.Println("not a float64")
}
}
再次运行结果:
$ go build && ./main
hello
not a float64
当assertion失败的时候,ok返回false,这样就不会发是panic行为。
类型switch
注意的是v必须定义成interface{},否则编译失败。
var v interface{} = "hello"
switch v.(type) {
case string:
fmt.Println("This is a string");
case int:
fmt.Println("This is a int");
default:
fmt.Println("This is default");
}
类型assertion和类型switch非常类似于C++里面多态类型之间的转换和判断。