类型断言提供了访问接口值底层具体值的方式.
变量名 := 接口名.(判断类型名)
- var i interface{
- } = "hello"
- s := i.(string)
- //f := i.(float64) // 编译错误, 因为 i 的值不为 float64
当只有一个返回值时, 返回值为对应类型的值, 而判断类型名与接口值类型不对应时, 程序会宕机 panic
此时我们需要第二种方式:
变量名, 是否为判断类型名结果 := 接口名.(判断类型名)
- var i interface{
- } = "hello"
- s,ok := i.(string)
当有两个返回值时, 第一个返回值为对应类型的值, 第二个返回值为布尔值, 是判断接口值是否为断言的类型, 而判断类型名与接口值类型不对应时, 第一个值会返回为断言类型的零值, 而不会产生 panic
- func main() {
- var i interface{}
- //s := i.(string) //panic: interface conversion: interface {} is nil, not string
- i = "string"
- s := i.(string)
- fmt.Println(s)
- ?
- s, ok := i.(string)
- fmt.Println(s, ok)
- ?
- f, ok := i.(float64)
- fmt.Println(f, ok)
- ?
- //f = i.(float64) // 报错 (panic)
- fmt.Println(f)
- }
运行结果:
- string
- string true
- 0 false
- 0
类型选择:
类型选择是对几个类型断言的分支选择结构, 注意 switch 后的 i.(具体类型) 换成了 i.(type)
switch v := i.(type) {
case 类型:
代码块
- }
- func do(i interface{}) {
- switch v := i.(type) {
- case int:
- fmt.Printf("Twice %v is %v\n", v, v*2)
- case string:
- fmt.Printf("%q is %v bytes long\n", v, len(v))
- default:
- fmt.Printf("I don't know about type %T!\n", v)
- }
- }
- ?
- func main() {
- do(21)
- do("hello")
- do(true)
- }
运行结果:
- Twice 21 is 42
- "hello" is 5 bytes long
- I don't know about type bool!
来源: http://www.bubuko.com/infodetail-3110928.html