系统考虑
3 分钟阅读
System considerations 系统考虑
原文:[https://go.dev/ref/spec#System considerations](https://go.dev/ref/spec#System considerations)
Package unsafe - unsafe 包
编译器知道的内置包unsafe,可以通过导入路径 “unsafe “访问,它为低级编程提供了便利,包括违反(violate)类型系统的操作。使用unsafe的包必须手动审查其类型安全,并且可能无法移植。该包提供以下接口:
| |
Pointer是一个指针类型,但是Pointer的值不能被解除引用。任何底层类型为uintptr的指针或值都可以被转换为底层类型Pointer的类型,反之亦然。在Pointer和uintptr之间转换的效果是由实现定义的。
| |
Alignof和Sizeof函数接收任意类型的表达式x,并分别返回假设变量v的对齐方式或大小,就像v通过var v = x声明一样。
Offsetof函数接收一个(可能是括号内的)选择器s.f,表示由s或*s表示的结构体中的字段f,并返回相对于该结构体地址的字段偏移量(字节)。如果f是一个嵌入字段,它必须可以通过结构体的字段在没有指针间接的情况下访问。对于带有字段f的结构体s:
| |
计算机体系结构可能要求内存地址被对齐;也就是说,变量的地址必须是一个因子的倍数,即变量类型的对齐方式。函数Alignof接收一个表示任何类型的变量的表达式,并返回(该类型的)变量的对齐方式,单位为字节。对于变量x:
| |
如果T是一个类型参数,或者它是一个包含可变大小的元素或字段的数组或结构体类型,则T类型的(变量)具有可变大小。否则,大小是常量。如果对 Alignof、Offsetof 和 Sizeof 的调用的实参(或 Offsetof 的选择器表达式 s.f 中的结构体 s)是恒定大小的类型,则它们是 uintptr 类型的编译时常量表达式。
Add 函数将 len 添加到 ptr 并返回更新后的指针 unsafe.Pointer(uintptr(ptr) + uintptr(len)) 。len实参必须是整数类型或无类型的常量。一个常量len实参必须可以用int类型的值表示;如果它是一个无类型的常量,则它会被赋予int类型。Pointer的有效使用规则仍然适用。
Slice 函数返回一个切片,其底层数组从 ptr 开始,其长度和容量为 len。Slice(ptr, len) 等于
| |
除了这样,还有一种特殊情况,如果 ptr 是 nil 并且 len 是零,Slice 返回 nil。
len实参必须是整数类型或无类型的常量。一个常量len实参必须是非负的,并且可以用int类型的值表示;如果它是一个无类型的常量,则它会被赋予int类型。在运行时,如果len是负的,或者如果ptr是nil而len不是0,会发生运行时恐慌。
Size and alignment guarantees 大小和对齐保证
对于数值型,以下大小是有保证的:
| |
以下最小对齐特性得到了保证:
- 对于任何类型的变量
x:unsafe.Alignof(x)至少是1。 - 对于结构体类型的变量
x:unsafe.Alignof(x)是x的每个字段f的所有值unsafe.Alignof(x.f)中最大的一个,但至少是1。 - 对于数组类型的变量
x:unsafe.Alignof(x)与数组元素类型的变量的对齐方式相同。
如果结构体或数组类型不包含大小大于0的字段(或元素),那么它的大小就是零。两个不同的zero-size变量在内存中可能有相同的地址。