类型和值的属性
9 分钟阅读
Properties of types and values 类型和值的属性
Underlying types 底层类型/基本类型
Each type T
has an underlying type: If T
is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T
itself. Otherwise, T
’s underlying type is the underlying type of the type to which T
refers in its declaration. For a type parameter that is the underlying type of its type constraint, which is always an interface.
每个类型T
都有一个底层类型。如果T
是预先声明的布尔型、数值型或字符串型之一,或者是一个类型字面量,那么对应的底层类型就是T
本身。否则,T
的底层类型是T
在其声明中所指的类型的底层类型。对于类型参数,则是其类型约束的底层类型,它总是一个接口。
|
|
The underlying type of string
, A1
, A2
, B1
, and B2
is string
. The underlying type of []B1
, B3
, and B4
is []B1
. The underlying type of P
is interface{}
.
string
、 A1
、 A2
、 B1
和 B2
的底层类型是 string。[]B1
、B3
和B4
的底层类型是[]B1
。P
的底层类型是interface{}
。
Core types 核心类型
Each non-interface type T
has a core type, which is the same as the underlying type of T
.
每个非接口类型T
都有一个核心类型,它与T
的底层类型相同。
An interface T
has a core type if one of the following conditions is satisfied:
如果满足以下条件之一,那么接口T
就有一个核心类型:
- There is a single type
U
which is the underlying type of all types in the type set ofT
; or - 存在一个单一的类型
U
,它是T
的类型集中所有类型的底层类型;或者 - the type set of
T
contains only channel types with identical element typeE
, and all directional channels have the same direction. T
的类型集只包含具有相同元素类型E
的通道类型,并且所有定向通道具有相同的方向。
No other interfaces have a core type.
其他接口都没有核心类型。
The core type of an interface is, depending on the condition that is satisfied, either:
根据满足的条件,接口的核心类型可以是:
- the type
U
; or - 类型
U
;或者 - the type
chan E
ifT
contains only bidirectional channels, or the typechan<- E
or<-chan E
depending on the direction of the directional channels present. - 如果
T
只包含双向通道,则为类型chan E
;或者为chan<- E
或<-chan E
类型,这取决于现存定向信道的方向。
By definition, a core type is never a defined type, type parameter, or interface type.
根据定义,核心类型绝不是已定义的类型、类型参数或接口类型。
Examples of interfaces with core types:
具有核心类型的接口的示例:
|
|
Examples of interfaces without core types:
没有核心类型的接口的示例:
|
|
Some operations (slice expressions, append
and copy
) rely on a slightly more loose form of core types which accept byte slices and strings. Specifically, if there are exactly two types, []byte
and string
, which are the underlying types of all types in the type set of interface T
, the core type of T
is called bytestring
.
一些操作(切片表达式、追加和复制)依赖于稍微宽松的核心类型形式,该形式接受字节切片和字符串。具体来说,如果正好有两种类型:[]byte
和string
,它们是接口T
的类型集中所有类型的底层类型,那么T
的核心类型就被称为bytestring
。
Examples of interfaces with bytestring
core types:
具有bytestring
核心类型的接口的例子:
|
|
Note that bytestring
is not a real type; it cannot be used to declare variables or compose other types. It exists solely to describe the behavior of some operations that read from a sequence of bytes, which may be a byte slice or a string.
注意bytestring
不是一个真正的类型;它不能用来声明变量(或组合其他类型)。它的存在只是为了描述一些从字节序列中读取的操作的行为,这些字节序列可能是字节切片或字符串。
Type identity 类型一致性
Two types are either identical or different.
两种类型要么一致,要么不同。
A named type is always different from any other type. Otherwise, two types are identical if their underlying type literals are structurally equivalent; that is, they have the same literal structure and corresponding components have identical types. In detail:
命名类型总是与任何其他类型不同。否则,如果两个类型的底层类型字面量在结构上是一致的,那么这两个类型就是相同的;也就是说,它们有相同的字面量结构,相应的组成部分拥有一致的类型。详细来说:
- Two array types are identical if they have identical element types and the same array length.
- 如果两个数组类型有一致的元素类型和相同的数组长度,那么它们就是一致的。
- Two slice types are identical if they have identical element types.
- 如果两个切片类型有一致的元素类型,那么它们就是一致的。
- Two struct types are identical if they have the same sequence of fields, and if corresponding fields have the same names, and identical types, and identical tags. Non-exported field names from different packages are always different.
- 如果两个结构体类型具有相同的字段序列,并且相应的字段具有一致的名称、一致的类型和一致的标签,那么它们就是一致的。来自不同包的不可导出的字段名总是不同的。
- Two pointer types are identical if they have identical base types.
- 如果两个指针类型有一致的基本类型,那么它们就是一致的。
- Two function types are identical if they have the same number of parameters and result values, corresponding parameter and result types are identical, and either both functions are variadic or neither is. Parameter and result names are not required to match.
- 如果两个函数类型有相同数量的参数和结果值,并且相应的参数和结果类型是相同的,并且两个函数要么都是可变的,要么都不是。参数和结果名称不需要匹配。
- Two interface types are identical if they define the same type set.
- 如果两个接口类型定义了相同的类型集,那么它们就是一致的。
- Two map types are identical if they have identical key and element types.
- 如果两个映射类型有一致的键和元素类型,它们就是一致的。
- Two channel types are identical if they have identical element types and the same direction.
- 如果两个通道类型有一致的元素类型和相同的方向,那么它们是一致的。
- Two instantiated types are identical if their defined types and all type arguments are identical.
- 如果两个实例化的类型的定义类型和所有类型参数都是一致的,那么它们就是一致的。
Given the declarations
给定声明:
|
|
these types are identical:
这些类型是一致的:
|
|
B0
and B1
are different because they are new types created by distinct type definitions; func(int, float64) *B0
and func(x int, y float64) *[]string
are different because B0
is different from []string
; and P1
and P2
are different because they are different type parameters. D0[int, string]
and struct{ x int; y string }
are different because the former is an instantiated defined type while the latter is a type literal (but they are still assignable).
B0
和B1
是不同的,因为它们是由不同的类型定义所创建的新类型;func(int, float64) *B0
和func(x int, y float64) *[]string
是不同的,因为B0
与[]string
是不同的;P1
和P2
是不同,因为它们是不同的类型参数。D0[int, string]
和struct{ x int; y string }
是不同的,因为前者是一个实例化的定义类型,而后者是一个类型字面量(但它们仍然是可分配的)。
Assignability 可分配性
A value x
of type V
is assignable to a variable of type T
("x
is assignable to T
") if one of the following conditions applies:
在以下这些情况中,V
类型的值x
是可以分配给T
类型的变量("x
可以分配给T
"):
V
andT
are identical.V
和T
是一致的。V
andT
have identical underlying types but are not type parameters and at least one ofV
orT
is not a named type.V
和T
有一致的底层类型,但不是类型参数,并且V
或T
中至少有一个不是命名类型。V
andT
are channel types with identical element types,V
is a bidirectional channel, and at least one ofV
orT
is not a named type.V
和T
是具有一致元素类型的通道类型,V
是一个双向通道,并且V
或T
中至少有一个不是命名类型。T
is an interface type, but not a type parameter, andx
implementsT
.T
是接口类型,但不是一个类型参数,并且x
实现了T
。x
is the predeclared identifiernil
andT
is a pointer, function, slice, map, channel, or interface type, but not a type parameter.x
是预先声明的标识符nil
,并且T
是一个指针、函数、切片、映射、通道或接口类型,但不是一个类型参数。x
is an untyped constant representable by a value of typeT
.x
是可由T
类型的值表示的非类型化的常量。
Additionally, if x
’s type V
or T
are type parameters, x
is assignable to a variable of type T
if one of the following conditions applies:
除此之外,如果x
的类型V
或T
是类型参数,并且满足以下条件之一,那么x
也可以分配给类型T
的变量:
x
is the predeclared identifiernil
,T
is a type parameter, andx
is assignable to each type inT
’s type set.x
是预先声明的标识符nil
,T
是类型参数,并且x
可以分配给T
的类型集中的每个类型。V
is not a named type,T
is a type parameter, andx
is assignable to each type inT
’s type set.V
不是命名类型,T
是一个类型参数,并且x
可以分配给T
的类型集中的每个类型。V
is a type parameter andT
is not a named type, and values of each type inV
’s type set are assignable toT
.V
是类型参数,T
不是命名类型,而V
的类型集中的每个类型的值都可以分配给T
。
Representability 可表示性
A constant x
is representable by a value of type T
, where T
is not a type parameter, if one of the following conditions applies:
如果满足以下条件之一,常量x
就可以被T
类型的值所表示,其中T
不是类型参数:
x
is in the set of values determined byT
.x
在由T
所确定的值的集合中。T
is a floating-point type andx
can be rounded toT
’s precision without overflow. Rounding uses IEEE 754 round-to-even rules but with an IEEE negative zero further simplified to an unsigned zero. Note that constant values never result in an IEEE negative zero, NaN, or infinity.T
是浮点类型,并且x
可以被舍入到T
的精度而不会溢出。四舍五入使用的是IEEE 754的四舍五入到偶数的规则,但IEEE的负0被进一步简化为无符号0。请注意,常量值绝不会出现IEEE负零、NaN或无穷大。T
is a complex type, andx
’s componentsreal(x)
andimag(x)
are representable by values ofT
’s component type (float32
orfloat64
).T
是复数类型,x
的组成real(x)
和imag(x)
可以用T
的组成类型(float32
或float64
)的值表示。
If T
is a type parameter, x
is representable by a value of type T
if x
is representable by a value of each type in T
’s type set.
如果T
是类型参数,并且x
可以由T
的类型集中的每个类型的值来表示,那么x
就可以由T
类型的值来表示。
x T x is representable by a value of T because
'a' byte 97 is in the set of byte values
97 rune rune is an alias for int32, and 97 is in the set of 32-bit integers
"foo" string "foo" is in the set of string values
1024 int16 1024 is in the set of 16-bit integers
42.0 byte 42 is in the set of unsigned 8-bit integers
1e10 uint64 10000000000 is in the set of unsigned 64-bit integers
2.718281828459045 float32 2.718281828459045 rounds to 2.7182817 which is in the set of float32 values
-1e-1000 float64 -1e-1000 rounds to IEEE -0.0 which is further simplified to 0.0
0i int 0 is an integer value
(42 + 0i) float32 42.0 (with zero imaginary part) is in the set of float32 values
|
|
Method sets 方法集
The method set of a type determines the methods that can be called on an operand of that type. Every type has a (possibly empty) method set associated with it:
类型的方法集确定了可以在该类型的操作数上调用的方法。每个类型都与一个(可能为空)方法集相关联:
- The method set of a defined type
T
consists of all methods declared with receiver typeT
. - 定义类型
T
的方法集包括所有用接收器类型T
声明的方法。 - The method set of a pointer to a defined type
T
(whereT
is neither a pointer nor an interface) is the set of all methods declared with receiver*T
orT
. - 指向定义类型
T
的指针(T
既不是指针也不是接口)的方法集是与接收器*T
或T
一起声明的所有方法的集合。 - The method set of an interface type is the intersection of the method sets of each type in the interface’s type set (the resulting method set is usually just the set of declared methods in the interface).
- 接口类型的方法集是该接口类型集中每个类型的方法集的交集(最终的方法集通常只是接口中声明的方法集)。
Further rules apply to structs (and pointer to structs) containing embedded fields, as described in the section on struct types. Any other type has an empty method set.
进一步的规则,应用于包含嵌入字段的结构体(和结构体指针),会在关于结构体类型的章节中描述。任何其他类型都有一个空的方法集。
In a method set, each method must have a unique non-blank method name.