系统考虑
5 分钟阅读
System considerations 系统考虑
原文:[https://go.dev/ref/spec#System considerations](https://go.dev/ref/spec#System considerations)
Package unsafe
- unsafe 包
The built-in package unsafe
, known to the compiler and accessible through the import path "unsafe"
, provides facilities for low-level programming including operations that violate the type system. A package using unsafe
must be vetted manually for type safety and may not be portable. The package provides the following interface:
编译器知道的内置包unsafe
,可以通过导入路径 “unsafe
“访问,它为低级编程提供了便利,包括违反(violate)类型系统的操作。使用unsafe
的包必须手动审查其类型安全,并且可能无法移植。该包提供以下接口:
|
|
A Pointer
is a pointer type but a Pointer
value may not be dereferenced. Any pointer or value of core type uintptr
can be converted to a type of core type Pointer
and vice versa. The effect of converting between Pointer
and uintptr
is implementation-defined.
Pointer
是一个指针类型,但是Pointer
的值不能被解除引用。任何底层类型为uintptr
的指针或值都可以被转换为底层类型Pointer
的类型,反之亦然。在Pointer
和uintptr
之间转换的效果是由实现定义的。
|
|
The functions Alignof
and Sizeof
take an expression x
of any type and return the alignment or size, respectively, of a hypothetical variable v
as if v
was declared via var v = x
.
Alignof
和Sizeof
函数接收任意类型的表达式x
,并分别返回假设变量v
的对齐方式或大小,就像v
通过var v = x
声明一样。
The function Offsetof
takes a (possibly parenthesized) selector s.f
, denoting a field f
of the struct denoted by s
or *s
, and returns the field offset in bytes relative to the struct’s address. If f
is an embedded field, it must be reachable without pointer indirections through fields of the struct. For a struct s
with field f
:
Offsetof
函数接收一个(可能是括号内的)选择器s.f
,表示由s
或*s
表示的结构体中的字段f
,并返回相对于该结构体地址的字段偏移量(字节)。如果f
是一个嵌入字段,它必须可以通过结构体的字段在没有指针间接的情况下访问。对于带有字段f
的结构体s
:
|
|
Computer architectures may require memory addresses to be aligned; that is, for addresses of a variable to be a multiple of a factor, the variable’s type’s alignment. The function Alignof
takes an expression denoting a variable of any type and returns the alignment of the (type of the) variable in bytes. For a variable x
:
计算机体系结构可能要求内存地址被对齐;也就是说,变量的地址必须是一个因子的倍数,即变量类型的对齐方式。函数Alignof
接收一个表示任何类型的变量的表达式,并返回(该类型的)变量的对齐方式,单位为字节。对于变量x
:
|
|
A (variable of) type T
has variable size if T
is a type parameter, or if it is an array or struct type containing elements or fields of variable size. Otherwise the size is constant. Calls to Alignof
, Offsetof
, and Sizeof
are compile-time constant expressions of type uintptr
if their arguments (or the struct s
in the selector expression s.f
for Offsetof
) are types of constant size.
如果T
是一个类型参数,或者它是一个包含可变大小的元素或字段的数组或结构体类型,则T
类型的(变量)具有可变大小。否则,大小是常量。如果对 Alignof
、Offsetof
和 Sizeof
的调用的实参(或 Offsetof
的选择器表达式 s.f
中的结构体 s
)是恒定大小的类型,则它们是 uintptr
类型的编译时常量表达式。
The function Add
adds len
to ptr
and returns the updated pointer unsafe.Pointer(uintptr(ptr) + uintptr(len))
[Go 1.17]. The len
argument must be of integer type or an untyped constant. A constant len
argument must be representable by a value of type int
; if it is an untyped constant it is given type int
. The rules for valid uses of Pointer
still apply.
Add
函数将 len
添加到 ptr
并返回更新后的指针 unsafe.Pointer(uintptr(ptr) + uintptr(len))
。len
实参必须是整数类型或无类型的常量。一个常量len
实参必须可以用int
类型的值表示;如果它是一个无类型的常量,则它会被赋予int
类型。Pointer的有效使用规则仍然适用。
The function Slice
returns a slice whose underlying array starts at ptr
and whose length and capacity are len
. Slice(ptr, len)
is equivalent to
Slice
函数返回一个切片,其底层数组从 ptr
开始,其长度和容量为 len
。Slice(ptr, len)
等于
|
|
except that, as a special case, if ptr
is nil
and len
is zero, Slice
returns nil
[Go 1.17].
除了这样,还有一种特殊情况,如果 ptr
是 nil
并且 len
是零,Slice
返回 nil
。
The len
argument must be of integer type or an untyped constant. A constant len
argument must be non-negative and representable by a value of type int
; if it is an untyped constant it is given type int
. At run time, if len
is negative, or if ptr
is nil
and len
is not zero, a run-time panic occurs [Go 1.17].
len
实参必须是整数类型或无类型的常量。一个常量len
实参必须是非负的,并且可以用int
类型的值表示;如果它是一个无类型的常量,则它会被赋予int
类型。在运行时,如果len
是负的,或者如果ptr
是nil
而len
不是0,会发生运行时恐慌 [Go 1.17]。
The function SliceData
returns a pointer to the underlying array of the slice
argument. If the slice’s capacity cap(slice)
is not zero, that pointer is &slice[:1][0]
. If slice
is nil
, the result is nil
. Otherwise it is a non-nil
pointer to an unspecified memory address [Go 1.20].
函数 SliceData
返回一个指向 slice
参数的底层数组的指针。如果切片的容量 cap(slice)
不为零,则该指针为 &slice[:1][0]
。如果 slice
为 nil
,则结果为 nil
。否则,它是一个指向未指定内存地址的非 nil
指针 [ Go 1.20]。
The function String
returns a string
value whose underlying bytes start at ptr
and whose length is len
. The same requirements apply to the ptr
and len
argument as in the function Slice
. If len
is zero, the result is the empty string ""
. Since Go strings are immutable, the bytes passed to String
must not be modified afterwards. [Go 1.20]
函数 String
返回一个 string
值,其底层字节从 ptr
开始,长度为 len
。 ptr
和 len
参数与函数 Slice
中的要求相同。如果 len
为零,则结果为空字符串 ""
。由于 Go 字符串是不可变的,因此传递给 String
的字节之后不能被修改。[Go 1.20]
The function StringData
returns a pointer to the underlying bytes of the str
argument. For an empty string the return value is unspecified, and may be nil
. Since Go strings are immutable, the bytes returned by StringData
must not be modified [Go 1.20].
函数 StringData
返回一个指向 str
参数的底层字节的指针。对于空字符串,返回值未指定,可能为 nil
。由于 Go 字符串是不可变的,因此 StringData
返回的字节不能被修改 [Go 1.20]。
Size and alignment guarantees 大小和对齐保证
For the numeric types, the following sizes are guaranteed:
对于数值型,以下大小是有保证的:
|
|
The following minimal alignment properties are guaranteed:
以下最小对齐特性得到了保证:
- For a variable
x
of any type:unsafe.Alignof(x)
is at least 1. - 对于任何类型的变量
x
:unsafe.Alignof(x)
至少是1。 - For a variable
x
of struct type:unsafe.Alignof(x)
is the largest of all the valuesunsafe.Alignof(x.f)
for each fieldf
ofx
, but at least 1. - 对于结构体类型的变量
x
:unsafe.Alignof(x)
是x
的每个字段f
的所有值unsafe.Alignof(x.f)
中最大的一个,但至少是1。 - For a variable
x
of array type:unsafe.Alignof(x)
is the same as the alignment of a variable of the array’s element type. - 对于数组类型的变量
x
:unsafe.Alignof(x)
与数组元素类型的变量的对齐方式相同。
A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero. Two distinct zero-size variables may have the same address in memory.
如果结构体或数组类型不包含大小大于0的字段(或元素),那么它的大小就是零。两个不同的zero-size变量在内存中可能有相同的地址。