Go语言类型断言的用法
Go语言中使用类型断言(type assertions)将接口转换成另一个接口,也可以将接口转换为另外的类型。
接口类型断言的语法格式如下:
类型断言有如下两种含义:
例如:
例如:
接口类型断言的语法格式如下:
i.(T)
- i 表示接口变量,如果是具体类型变量,则编译器会报“non-interface type xxx on left”错误。
- T 表示一个具体的类型(也可为接口类型)。
类型断言有如下两种含义:
- 如果 T 是一个具体类型名,则类型断言用于判断接口变量 i 绑定的实例类型是否就是具体类型T。
- 如果 T 是一个接口类型名,则类型断言用于判断接口变量i绑定的实例类型是否同时实现了 T 接口。
类型断言的语法
类型断言的语法有下面两种。1) 直接赋值模式
语法格式为:t := i.(T)
- T 是具体类型名,此时如果接口 i 绑定的实例类型就是具体类型 T,则变量 t 的类型就是T,变量t的值就是接口绑定的实例值的副本(当然实例可能是指针值,那就是指针值的副本)。
- T 是接口类型名,如果接口 i 绑定的实例类型满足接口类型T,则变量 t 的类型就是接口类型 T,t 底层绑定的具体类型实例是 i 绑定的实例的副本(当然实例可能是指针值,那就是指针值的副本)。
- 如果上述两种情况都不满足,则程序抛出 panic。
例如:
package main import " fmt" type Inter interface { Ping () Pang() } type Anter interface { Inter String() } type St struct{ Name string } func (St) Ping() { println ("ping") } func (*St) Pang() { println ("pang") } func main() { st := &St{"andes"} var i interface{}= st //判断绑定的实例是否实现了接口类型Inter t := i.(Inter) t. Ping() t.Pang() //如下语句会引发panic,因为i没有实现接口Anter //p :=i. (Anter) //p. String () //判断i绑定的实例是否就是具体类型St s :=i. (*St) fmt.Printf ("%s", s.Name) }
2) comma,ok表达式模式
语法格式如下:if t, ok := i.(T); ok{ }
- T 是具体类型名,此时如果接口 i 绑定的实例类型就是具体类型 T,则 ok 为 true,变量 t 的类型就是 T,变量 t 的值就是接口绑定的实例值的副本(当然实例可能是指针值,那就是指针值的副本)。=
- T 是接口类型名,此时如果接口 i 绑定的实例的类型满足接口类型 T,则 ok 为 true,变量 t 的类型就是接口类型 T,t 底层绑定的具体类型实例是 i 绑定的实例的副本(当然实例可能是指针值,那就是指针值的副本)。
- 如果上述两个都不满足,则 ok 为 false,变量 t 是 T 类型的“零值”,此种条件分支下程序逻辑不应该再去引用 t,因为此时的 t 没有意义。
例如:
package main import "fmt" type Inter interface { Ping () Pang () } type Anter interface { Inter String() } type St struct { Name string } func (St) Ping() { println ("ping") } func (*St) Pang() { println ("pang") } func main() { st := &St{ "andes"} var i interface{} = st //判断i绑定的实例是否实现了接口类型Inter if t, ok:= i. (Inter) ; ok{ t.Ping() //ping t. Pang() //pang } if p, ok := i. (Anter); ok { //i没有实现接口Anter,所以程序不会执行到这里 p.String () } //判断i绑定的实例是否就是具体类型st if s, ok := i.(*St);ok { fmt.Printf("%s", s.Name) //andes } }运行结果如下:
ping
pang
andes