golang类型系统
2021-11-19 09:40:29 31 举报
AI智能生成
golang类型系统
作者其他创作
大纲/内容
类型
内置类型(basic type)
字符串 string
布尔类型 bool
数值类型
complex64、complex128
int8、uint8(byte)、int16、uint16、int32(rune)、uint32、int64、uint64、int、uint、uintptr
float32、float64
组合类型(composite type)
指针类型(Pointer types)
结构体类型(Struct types)
函数类型(Function types)
数组类型(Array types)
切片类型(Slice types)
映射类型(Map types)
通道类型(Channel types)
接口类型(Interface types)
自定义类型(Type definitions)
type NewTypeName SourceType
类型元数据
基本类型元数据
type _type struct{
size uintptr // 大小
ptrdata uintptr // size of memory prefix holding all pointers
hash uint32 // 类型 Hash
tflag tflag // 类型的特征标记
align uint8 // _type 作为整体变量存放时的对齐字节数
fieldalign uint8 // 当前结构字段的对齐字节数
kind uint8 // 基础类型枚举值和反射中的 Kind 一致,kind 决定了如何解析该类型
alg *typeAlg // 指向一个函数指针表,该表有两个函数,一个是计算类型 Hash 函数。另一个是比较两个类型是否相同的 equal 函数
gcdata *byte // GC 相关
str nameOff // str 用来表示类型名称字符串在编译后二进制文件中某个 section、 的偏移量
ptrToThis typeOff // ptrToThis 用来表示类型元信息的指针在编译后二进制文件中某个section 偏移量,有连接器负责填充
}
size uintptr // 大小
ptrdata uintptr // size of memory prefix holding all pointers
hash uint32 // 类型 Hash
tflag tflag // 类型的特征标记
align uint8 // _type 作为整体变量存放时的对齐字节数
fieldalign uint8 // 当前结构字段的对齐字节数
kind uint8 // 基础类型枚举值和反射中的 Kind 一致,kind 决定了如何解析该类型
alg *typeAlg // 指向一个函数指针表,该表有两个函数,一个是计算类型 Hash 函数。另一个是比较两个类型是否相同的 equal 函数
gcdata *byte // GC 相关
str nameOff // str 用来表示类型名称字符串在编译后二进制文件中某个 section、 的偏移量
ptrToThis typeOff // ptrToThis 用来表示类型元信息的指针在编译后二进制文件中某个section 偏移量,有连接器负责填充
}
其它类型信息
structtype
type structtype struct {
typ _type
pkgPath name //包路径
fields []structfield //字段
}
typ _type
pkgPath name //包路径
fields []structfield //字段
}
prttype
type ptrtype struct {
typ _type
elem *_type
}
typ _type
elem *_type
}
slicetype
type slicetype struct {
typ _type
elem *_type //记录的元素类型
}
typ _type
elem *_type //记录的元素类型
}
...
uncommontype(自定义类型的额外元数据)
type uncommontype struct {
pkgpath nameOff // 包路径
mcount uint16 // number of methods
xcount uint16 // number of exported methods
moff uint32 // offset from this uncommontype to [mcount]method
_ uint32 // unused
}
pkgpath nameOff // 包路径
mcount uint16 // number of methods
xcount uint16 // number of exported methods
moff uint32 // offset from this uncommontype to [mcount]method
_ uint32 // unused
}
interface
非空接口
type iface struct {
tab *itab
data unsafe.Pointer //动态类型数据
}
tab *itab
data unsafe.Pointer //动态类型数据
}
itab
type itab struct {
inter *interfacetype // 接口自身的元信息
_type *_type // 具体类型的元信息
link *itab
bad int32
hash int32 // _type里也有一个同样的hash,此处多放一个是为了方便运行接口断言
fun [1]uintptr // 函数指针,指向具体类型所实现的方法
}
inter *interfacetype // 接口自身的元信息
_type *_type // 具体类型的元信息
link *itab
bad int32
hash int32 // _type里也有一个同样的hash,此处多放一个是为了方便运行接口断言
fun [1]uintptr // 函数指针,指向具体类型所实现的方法
}
当接口类型与动态类型确定时,itab就会唯一确定,所以可以复用itab
空接口
type eface struct {
_type *_type //动态类型元数据
data unsafe.Pointer //动态类型数据
}
_type *_type //动态类型元数据
data unsafe.Pointer //动态类型数据
}
类型断言
空接口.(具体类型)
判断空接口中_type是否是具体类型的类型元数据(通过hash比较)
非空接口.(具体类型)
通过<接口类型,具体类型的_type>找到的itab是否与具体类型的itab一致就行了
空接口.(非空接口)
其实就是判断,空接口的_type是否实现了非空接口,可以先去itab缓存里面通过<非空接口类型,空接口的_type>进行查找,如果找到并且fun[0]=0,就代表实现该非空接口。如果没有找到,就通过itab中的fun查找是否实现了非空接口中的所有方法
非空接口.(非空接口)
与空接口.(非空接口)一致
反射
基本概念
运行时反射是程序在运行期间检查其自身结构的一种方式
三大法则
从 interface{} 变量可以反射出反射对象
从反射对象可以获取 interface{} 变量
要修改反射对象,其值必须可设置
func main() {
i := 1
v := reflect.ValueOf(i)
v.SetInt(10)
fmt.Println(i)
}
go是值传递的所以如上这周就会panic,或者对于一个Struct的未暴露字段进行设置也会panic
i := 1
v := reflect.ValueOf(i)
v.SetInt(10)
fmt.Println(i)
}
go是值传递的所以如上这周就会panic,或者对于一个Struct的未暴露字段进行设置也会panic
引用
https://github.com/aceld/golang/blob/main/4%E3%80%81interface.md
https://www.bilibili.com/video/BV1iZ4y1T7zF?p=2
https://draveness.me/golang/docs/part2-foundation/ch04-basic/golang-interface/#424-%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80
0 条评论
下一页