1. 静态类型 static type
声明变量时的类型
var i int //int是静态类型
var str string //string是静态类型 编码时能确定的,可看见的类型是静态类型
2. 动态类型 dynamic type
程序运行时才能确定具体类型的类型是动态类型
var i interface{} //空接口可以接受任何类型,因此声明时不确定是什么具体类型
i = 25 //赋值为int,但静态类型还是interface{}, 运行时,i的类型才会改变为int
i = "abcdefg" //赋值为string,但静态类型还是interface{},运行时,i的类型才会改变为string
3. 接口组成
接口由type和data组成
var temp interface{}
temp = 25
执行temp = 25后,interface的type=int data=25
3.1 接口细分
接口分为非空接口iface和空接口eface
iface带有一组函数的接口
//非空接口
type ifcae struct {
tab *itab //类型信息
data unsafe.Pointer //数据指针
}
// 非空接口的类型信息
type itab struct {
inter *interfacetype // 接口定义的类型信息
_type *_type // 接口实际指向值的类型信息 l
ink *itab
bad int32
inhash int32
fun [1]uintptr //接口方法实现列表,即函数地址列表,按字典序排序
}
eface空接口
type eface struct {
_type *_type //类型
data unsafe.Pointer //数据指针
}
3.2 理解动态类型
3.2.1 iface
var reader io.Reader
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
return nil, err
}
reader = tty
io.Reader接口包含Read(),所以是非空接口 执行var reader io.Reader后,此时reader的静态类型是io.Reader,动态类型是nil,函数集为Read(),数据指针为nil 执行reader = tty后,此时reader的静态类型还是io.Reader,动态类型改变为*io.File,函数集为Read(),数据指针为tty
3.2.2 eface
var empty interface{}
tty, err := os.OpenFile("dev/tty", os.O_RDWR, 0)
if err != nil {
return nil, err
}
empty = tty
执行var empty interface{}后,此时empty的静态类型为nil,数据指针为nil 执行empty = tty后,此时empty的静态类型改变为*os.File,数据指针为tty