- unsafe 包广泛使用在和操作系统交互的低级包中,例如:runtime, os, syscall, net。普通程序不需要使用
-
Sizeof 报告参数在内存中的字节长度,参数可以是任何类型的表达式。Sizeof结果是常量,可以用作数组长度或计算其他的常量。
-
聚合类型的值的长度至少是它的成员或元素长度之和。或用于对齐的内存空位,比长度之和稍大。
-
32 位的系统上,字的长度是 4 个字节; 64 位的系统上是 8 个字节:
类型 大小 bool 1 个字节 intN, uintN, floatN, complexN N/8 个字节 int, uint, uintptr 1 个字 *T 1 个字 string 2 个字(数据,长度) []T 3 个字(数据,长度,容量) map 1 个字 func 1 个字 chan 1 个字 interface 2 个字(类型,长度) -
Alignof 报告参数类型要求的对齐方式,返回一个常量
-
Offsetof(x.f) 计算成员 f 相对于结构体 x 起始地址的偏移量,内存空位也计算在内
//64位上,sizeof:32 alignof: 8 var x struct { a bool //sizeof:1 alignof:1 offsetof:0 b int16 //sizeof: 2 alignof: 2 offsetof: 2 c []int //sizeof: 24 alignof: 8 offsetof: 8 }
-
一个普通的指针 *T 可以转换为 unsafe.Pointer 类型的指针,然后再转换回普通指针,而且类型不一定和 *T 相同
func Float64bits(f float64) uint64 { return *(*uint64)(unsafe.Pointer(&f)) }
-
unsafe.Pointer 类型可以转换为 uintptr 类型,以便对地址进行数值计算。但是从 uintptr 转换 为 unsafe.Pointer 可能破坏类型系统
-
可以用 reflect.DeepEqual 比较组合类型,或者不能用 == 比较的值
-
对于 map 和 slice,DeepEqual 比较 nil 和 空值的结果为不相等:
var a, b []string = nil, []string{} fmt.Println(reflect.DeepEqual(a, b)) //false var c, d map[string]int = nil, make(map[string]int) fmt.Println(reflect.DeepEqual(c, d)) //false
-
在 Go 项目中定义 .c 文件,其中 #include C 库的头文件以及定义包装函数
-
在 .go 文件 import "C" 之前在注释中声明 cgo 的编译器参数 -I -L 发现头文件以及库,inlucde 以及函数声明
-
在 go 代码中使用 C. 来调用 C 语言函数
- 新手避免使用 reflect 和 unsafe 包,需要时再复习最后两张。
(完)