类型断言、type-switch、反射
类型断言
检测使用多态时指向对象的引用类型是否能变为更加具体的引用类型
AB接口内嵌入的A和B两个接口
number结构体实现了AB接口。
A num = new (number)
numab,err := num.(AB)//类型断言,判断A接口引用类型是否可以变为AB(更具体的引用类型)
类型断言事不能转为结构体类型的引用的,只能是接口类型的引用,而且,只能是内嵌了此时的接口类型的接口的引用。,numab是转换成功以后的AB类型的引用(指向那个对象)
if v, ok := varI.(T); ok { // checked type assertion
Process(v)
return
}
// varI is not of type T
type-switch(这是个特殊的switch):
//对象的具体数据类型
switch t := areaIntf.(type) {
case *Square:
fmt.Printf("Type Square %T with value %v\n", t, t)
case *Circle:
fmt.Printf("Type Circle %T with value %v\n", t, t)
case nil:
fmt.Printf("nil value: nothing to check?\n")
default:
fmt.Printf("Unexpected type %T\n", t)
}
Go 语言规范定义了接口方法集的调用规则:
类型 *T 的可调用方法集包含接受者为 *T 或 T 的所有方法集
类型 T 的可调用方法集包含接受者为 T 的所有方法
类型 T 的可调用方法集不包含接受者为 *T 的方法
接口类型的变量可以存储实现了该接口的结构体对象的指针
也可以存储引用,不过条件是被实现的所有方法的接收者只能是类型的引用,而不能是指针。
一般直接用指针吧,用引用还得复制结构体。麻烦。
反射包:reflect
两个数据类型:Type、Value
获取Type TypeOf(object)Type
获取Value ValueOF(Object)Value
//通过Type可以获取对象的类型
//通过Value可以更改值,也可以获取Type,就是上一句话那个Type
const (
Invalid Kind = iota
Bool
Int
Int8
Int16
Int32
Int64
Uint
Uint8
Uint16
Uint32
Uint64
Uintptr
Float32
Float64
Complex64
Complex128
Array
Chan
Func
Interface
Map
Ptr
Slice
String
Struct
UnsafePointer
)
Type的Kind方法返回类型,上面的那些常量。
反射结构体
(Value)NumField()返回结构体内的字段数量,通过Field(i int)来获取该Field。
调用方法value.Method(0).Call(nil)