深入源码分析go类型系统
Ø runtime/type.h
go类型描述的静态信息
//type go类型最通用定义,go的类型系统通过这个数据结构来进行驱动 //Type是类型信息结构体中公共的部分 20 struct Type 21 { 22 uintptr size; //类型大小 23 uint32 hash; //hash值 24 uint8 _unused; 25 uint8 align; //对齐 26 uint8 fieldAlign; //field对齐 27 uint8 kind; //reflect包中的Kind类型就是这个,它是个类型的枚举值 28 Alg *alg; 29 void *gc; //垃圾回收相关 30 String *string; 31 UncommonType *x; //指向指针,该指针指向的struct 中包含该类型实现的函数指针数组 32 Type *ptrto; 33 byte *zero; // ptr to the zero value for this type 34 }; |
// 非接口类型method描述数据结构 36 struct Method 37 { 38 String *name; 39 String *pkgPath; 40 Type *mtyp; 41 Type *typ; 42 void (*ifn)(void); 43 void (*tfn)(void); 44 }; 45 //具体类型的methods集合 46 struct UncommonType 47 { 48 String *name; 49 String *pkgPath; 50 Slice mhdr; 51 Method m[]; 52 }; |
//有methods 的interface 编译器构造的静态数据结构 54 struct IMethod 55 { 56 String *name; 57 String *pkgPath; 58 Type *type; 59 }; 60 61 struct InterfaceType 62 { 63 Type; 64 Slice mhdr; 65 IMethod m[]; 66 };
// 空接口interface{} 编译器不会为该种类型构造一个静态数据结构 空接口在赋值后才有意义,单单声明个空接口是没有意义的
|
Ø runtime/type.h
//接口赋值时编译器构造的动态数据结构
//其他类型赋值给interfac{},编译器动态构造的数据结构 189 struct Eface 190 { 191 Type* type; //指向具体类型 192 void* data; //类型变量的值 193 };
|
//其他类型赋值给非空接口,编译器构造的数据结构 184 struct Iface 185 { 186 Itab* tab; //接口动态赋值时数据结构 187 void* data; //类型值 188 };
// 具体类型变量赋值给非空接口类型变量时,编译器构造的数据结构 472 struct Itab 473 { 474 InterfaceType* inter; //指向接口静态类型描述,见上文InterfaceType结构 475 Type* type; //指向结构被赋值的具体变量的类型描述 476 Itab* link; 477 int32 bad; 478 int32 unused; 479 void (*fun[])(void); //拷贝具体类型变量的函数指针到该数组 480 }; |
|
|
l 接口是可被实例化的类型,不仅是语言上的约束规范;当我们创建接变量时,将会为其分配部分内存空间(此时接口没有任何价值,不能使用);当将type实例赋值时给接口变量时才分配全部空间(包括实例变量值或指针的拷贝)和初始化全部数据结构。单单声明一个接口变量,而不对其赋值,是没有意义的。
$GOROOT/src/pkg/runtime/runtime.h
178 struct Iface 179 { 180 Itab* tab; 181 void* data; 182 };
|