内置函数
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不一定需要接受任意的实参类型,但必须支持布尔型、数字型和字符串型的打印。