内置函数
8 分钟阅读
Built-in functions 内置函数
内置函数是预先声明的。它们像其他函数一样被调用,但其中一些函数接受一个类型而非表达式作为其第一个实参。
内置函数没有标准的Go类型,所以它们只能出现在调用表达式中;它们不能作为函数值使用。
Close
对于一个核心类型为通道的参数ch
,内置函数close
记录了通道上将不再有任何值被发送。如果ch
是一个仅接收的通道,那么(关闭它)是一个错误。发送到或关闭一个已关闭的通道会导致运行时恐慌。关闭nil
通道也会引起运行时恐慌。在调用close
后,并且在任何先前发送的值被接收后,接收操作将返回通道类型的零值
而不阻塞。多值接收操作会返回一个接收值以及通道是否被关闭的指示。
Length and capacity 长度和容量
内置函数len
和cap
接受各种类型的实参并返回int
类型的结果。该实现保证结果总是适合于一个int
。
Call Argument type Result
调用 实参类型 结果
len(s) string type string length in bytes
[n]T, *[n]T array length (== n)
[]T slice length
map[K]T map length (number of defined keys)
chan T number of elements queued in channel buffer
type parameter see below
cap(s) [n]T, *[n]T array length (== n)
[]T slice capacity
chan T channel buffer capacity
type parameter see below
如果参数类型是一个类型参数P
,调用len(e)
(或cap(e)
)必须对P
的类型集中的每个类型有效。其结果是(类型对应P
被实例化时使用的类型实参的)实参的长度(或容量)。
切片的容量是底层数组中分配到的元素的数量。在任何时候,以下关系都是成立的:
0 <= len(s) <= cap(s)
nil
切片、nil
映射或nil
通道的长度是0
。nil
切片或nil
通道的容量是0。
如果s
是一个字符串常量,那么表达式len(s)
就是常量。如果s
的类型是一个数组或指向数组的指针,并且表达式s
不包含通道接收或(非常量)函数调用,那么表达式len(s)
和cap(s)
是常量;在这种情况下,s
不被求值。否则,len
和cap
的调用不是常量,s
被求值。
|
|
Allocation 分配
内置函数new
接收一个类型T
,在运行时为该类型的变量分配存储空间,并返回一个指向它的*T
类型的值。该变量被初始化,如初始值一节中所述。
|
|
举例来说
|
|
为一个S
类型的变量分配存储空间,初始化它(a=0
, b=0.0
),并返回一个包含该位置地址的*S
类型的值。
Making slices, maps and channels 制作切片、映射和通道
内置函数make
接收一个类型T
,后面可以选择一个特定类型的表达式列表。T
的核心类型必须是一个切片、映射或通道
。它返回一个类型为T
(不是*T
)的值。内存被初始化,如初始值一节中所述。
Call Core type Result
make(T, n) slice slice of type T with length n and capacity n
make(T, n, m) slice slice of type T with length n and capacity m
make(T) map map of type T
make(T, n) map map of type T with initial space for approximately n elements
make(T) channel unbuffered channel of type T
make(T, n) channel buffered channel of type T, buffer size n
每个大小实参n
和m
必须是整型,或者是一个只包含整型的类型集,或者是一个无类型的常量。一个常量大小参数必须是非负数,并且可以用int
类型的值表示;如果它是一个无类型的常量,它被赋予int
类型。如果n
和m
都被提供并且是常量,那么n
必须不大于m
。对于切片和通道,如果n
在运行时是负数或者大于m
,就会发生运行时恐慌。
|
|
调用map
类型和大小提示n
的make
将创建一个初始空间可容纳n
个map元素的map
。具体的行为是依赖于实现的
。
Appending to and copying slices 追加和复制切片
内置函数append
和copy
可以帮助进行常见的切片操作。对于这两个函数,其结果与实参所引用的内存是否重叠无关。
The variadic function append
appends zero or more values x
to a slice s
and returns the resulting slice of the same type as s
. The core type of s
must be a slice of type []E
. The values x
are passed to a parameter of type ...E
and the respective parameter passing rules apply. As a special case, if the core type of s
is []byte
, append
also accepts a second argument with core type bytestring
followed by ...
. This form appends the bytes of the byte slice or string.
可变参数函数append
将零个或多个值x
追加到一个切片s
,并返回与s
相同类型的结果切片。值x
被传递给一个类型为...E
的参数,各自的参数传递规则适用。作为一个特例,如果s
的核心类型是[]byte
,append
也接受第二个参数,其核心类型是bytestring,后面是...
。这种形式追加了字节切片或字符串的字节。
|
|
如果s
的容量不足以容纳额外的值,append
会分配一个新的、足够大的底层数组,同时容纳现有的切片元素和额外的值。否则,append
复用原来的底层数组。
|
|
函数copy
将切片元素从源src
复制到目标dst
,并返回复制的元素数量
。两个参数的核心类型必须是具有一致的元素类型的切片。复制的元素数是len(src)
和len(dst)
中的最小值。作为一种特殊情况,如果目标的核心类型是[]byte
,copy
也接受一个核心类型为bytestring的源参数。这种形式将字节切片或字符串中的字节复制到字节切片中。
|
|
例子:
|
|
Deletion of map elements 删除映射元素
内置函数delete
可以从映射m
中删除键值
为k
的元素,值k
必须可以分配给m
的键类型。
|
|
如果m
的类型是类型参数,那么该类型集合中的所有类型必须是映射,并且它们必须都有相同的键类型
。
如果映射m
是nil
或者元素m[k]
不存在,delete就是一个空操作。
Manipulating complex numbers 操纵复数
有三个函数组装
和分解
复数。内置函数 complex
从浮点实部和虚部构造一个复数值,而 real
和 imag
则提取复数值的实部和虚部。
|
|
实参的类型和返回值相对应。对于complex
函数,两个实参必须是相同的浮点类型,返回类型是具有对应浮点成分的复数类型:float32
类型的实参对应comple64
复数类型,而float64
类型的实参对应comple128
复数类型。如果其中一个实参的值是一个无类型常量,那么它首先会被隐式转换为另一个实参的类型。如果两个参数都求值为无类型常量,那么它们必须是非复数
,或者它们的虚数部分必须为零,这样函数的返回值就是一个无类型的复数常量。
对于real
和imag
,实参必须是复数类型,返回类型是相应的浮点类型:float32
对应complex64
,float64
对应complex128
。如果实参的值是一个无类型的常量,它必须是一个数字,这样函数的返回值就是一个无类型的浮点常量。
real
和imag
函数一起构成了复数的逆运算,所以对于一个复数类型Z
的值z
来说,z == Z(complex(real(z), imag(z)))
。
如果这些函数的操作数都是常量,返回值就是一个常量。
|
|
Arguments of type parameter type are not permitted.
不允许使用参数类型的实参。
Handling panics 处理恐慌
两个内置函数,panic
和recover
,协助报告和处理运行时恐慌和程序定义的错误情况。
|
|
在执行函数F
时,对panic
的显式调用或运行时恐慌终止了F
的执行,然后被F
延迟的任何函数会照常执行。接下来,任何被F
的调用者延迟的函数都会被运行,以此类推,直到被执行中的goroutine中的顶级函数所延迟的任何函数。此时,程序被终止,错误情况被报告,包括panic
的实参值。这个终止过程被称为panicking
。
|
|
recover
函数允许程序管理 panicking goroutine 的行为。假设函数G
延迟了一个调用recover
的函数D
,并且在G
执行的同一个goroutine上的一个函数发生了恐慌。当被延迟函数的运行到达D
时,D
调用recover
的返回值将是传递给调用panic
的值。如果D
正常返回,没有启动新的panic
,则 panicking goroutine 停止。在这种情况下,G
和对panic
的调用之间调用的函数的状态被丢弃,并恢复正常执行。G
在D
之前被延迟的任何函数随后被运行,G
的执行通过返回给它的调用者而终止。
如果以下任何一个条件成立,recover
的返回值为nil
:
panic
的参数是空的。- goroutine没有陷入panicking。
recover
不是由被延迟函数直接调用的。
下面的例子中的protect
函数调用了函数实参g
,并保护调用者免受g
引发的运行时恐慌。
|
|
Bootstrapping 引导
目前的实现提供了几个在引导(bootstrapping)过程中有用的内置函数。为了完整起见,这些函数被记录下来,但不保证会留在语言中。它们并不返回结果。
|
|
实现限制:print
和println
不一定需要接受任意的实参类型,但必须支持布尔型、数字型和字符串型的打印。