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
ICP备案:
公安联网备案: