Go基础:内置函数的介绍与使用

376 阅读7分钟

Go基础:内置函数的介绍与使用

内置函数的源码都在builtin包中的builtin.go文件里。

append()

函数定义

func append(slice []Type, elems ...Type) []Type

append()内置函数将元素追加到片段的末尾。如果目的地有足够的容量,那么它将被重新许可以容纳新元素。否则,将分配一个新的基础数组。append()返回更新的切片。因此,有必要将append()的结果存储在保存切片本身的变量中。

从函数定义可以看出这是一个变长函数。变长函数的特点是在参数列表最后的类型名称之前使用省略号...。调用边长函数的时候可以传递任意数目的参数。

使用示例

使用append()内置函数需要注意以下几点:

  1. append函数是用来在slice末尾追加一个或者多个元素。
  2. 当追加元素时,发现slice的len>cap时,会重新开辟一个2*cap的内存空间去存储追加过元素的slice。
  3. 如果追加元素后slice的len<=cap,则append返回的新生成的slice的内存地址依旧是传入的slice参数的内存地址。
  4. 注意:追加的元素是之前元素的引用。因此,append属于浅拷贝
// 因为append后slice指向的底层数组可能发生改变
// 通常将append的调用结果再次赋值给传入的slice
slice = append(slice, elem1, elem2)
slice = append(slice, anotherSlice...)

作为一种特殊情况,将字符串附加到字节切片是合法的,如下所示:

slice = append([]byte("hello "), "world"...)

copy()

函数定义

func copy(dst, src []Type) int

copy()内置函数将元素从源切片复制到目标切片。源和目标可能重叠。copy()返回复制的元素数,它是len(src)len(dst)的最小值。

作为一种特殊情况,它还会将字符串中的字节复制到字节片中。

注意事项

  1. 不同类型的切片无法复制
  2. 如果dst的长度大于src的长度,将src中对应位置上的值替换dst中对应位置的值
  3. 如果dst的长度小于src的长度,多余的将不做替换
  4. 同样属于浅拷贝

delete()

函数定义

func delete(m map[Type]Type1, key Type)

delete()内置函数从映射中删除具有指定键(m[key])的元素。

如果m是nil或者没有这样的元素,delete()就不执行任何操作。

删除函数不返回任何值。

len()

函数定义

func len(v Type) int

len()内置函数根据其类型返回v的长度。

  • 数组:v中的元素数
  • 指向数组的指针:*v中的元素数(即使v为nil)
  • slicemap:v中的元素数量; 如果v为nil,则len(v)为零
  • 字符串:v中的字节数
  • Channel:在通道缓冲区中排队(未读)的元素数;如果v为nil,则len(v)为零

注意事项

关于包含中文的字符串

由于 Go 语言的字符串都以 UTF-8 格式保存,每个中文占用 3 个字节,因此使用 len() 获得两个中文文字对应的 6 个字节。

如果希望按习惯上的字符个数来计算,就需要使用 Go 语言中 UTF-8 包提供的 RuneCountInString() 函数,统计 Uncode 字符数量。

utf8.RuneCountInString("嘉夫")

cap()

函数定义

func cap(v Type) int

cap()内置函数根据其类型返回v的容量。

  • 数组:v中的元素数(与len(v)相同)
  • 指向数组的指针:*v中的元素数(与len(v)相同)
  • slice:切片后可达到的最大长度,如果v为nil,则cap(v)为零
  • Channel:通道缓冲容量,以元素为单位,如果v为nil,则cap(v)为零

make()

函数定义

func make(t Type, size ...IntegerType) Type

make()内置函数分配并初始化slicemapchan类型的对象。

像new一样,第一个参数是类型,而不是值。与new不同,make的返回类型与其参数的类型相同,而不是指向它的指针。

结果的规格取决于类型:

  • slice:大小指定长度
    • 切片的容量等于其长度
    • 可以提供第二个整数参数来指定不同的容量
    • 它必须不小于长度
    • 例如,make([] int,0,10)分配一个大小为10的基础数组
    • 并返回一个长度为0且容量为10的切片,该切片由该基础数组支持
  • map:为空的map分配足够的空间以容纳指定数量的元素
    • 该大小可以省略,在这种情况下,分配的起始大小较小
  • Channel:使用指定的缓冲区容量初始化通道的缓冲区
    • 如果为零或忽略大小,则通道不缓冲

new()

函数定义

func new(Type) *Type

new()内置函数为变量分配内存。

第一个参数是类型,而不是值,返回的值是指向该类型新分配的零值的指针

close()

函数定义

func close(c chan<- Type)

close()内置函数关闭一个双向或仅发送的通道。

它只能由发送者执行,而不能由接收者执行,并且具有在接收到最后一个发送值之后关闭通道的作用。

从关闭的通道c接收到最后一个值后,从c的任何接收都将成功执行而不会阻塞,返回通道元素的零值。

对于关闭的通道,x,ok:= <- c 格式还将ok设置为false。

panic()

函数定义

func panic(v interface{})

panic()内置函数停止当前goroutine的正常执行。

当函数F调用panic()时,F的正常执行立即停止。F推迟执行的所有函数都以常规方式运行,然后F返回其调用方。

对调用者G而言,F的调用就像调用panic()一样,终止G的执行并运行所有延迟函数, 直到执行的goroutine中的所有功能都以相反的顺序停止为止。

此时,程序将以非零的退出代码终止。

此终止序列称为panicking,可以通过内置函数recover()控制。

recover()

函数定义

func recover() interface{}

recover()内置函数允许程序管理恐慌性goroutine的行为。

在延迟函数(但不是由其调用的任何函数)中执行恢复调用将通过恢复正常执行来停止恐慌序列,并检索传递给panic调用的错误值。如果在延迟函数之外调用了recover,它将不会停止紧急处理序列。

在这种情况下,或者当goroutine没有惊慌时,或者如果提供给panic的参数为nil,则recover返回nil。

因此,来自recover的返回值将报告goroutine是否感到恐慌。

其他内置函数

复数相关

complex()

func complex(r, i FloatType) ComplexType

complex()内置函数根据两个浮点值构造一个复杂的值。

实部和虚部必须具有相同的大小,即float32或float64(或可分配给它们),并且返回值将是相应的复数类型(对于float32,complex64,对于float64,complex128)。

real()

func real(c ComplexType) FloatType

real()内置函数返回复数c的实数部分。

返回值将是对应于c类型的浮点类型。

imag()

imag()内置函数返回复数c的虚部。

返回值将是对应于c类型的浮点类型。

打印相关

print()

print()内置函数以特定于实现的方式格式化其参数,并将结果写入标准错误

print()对于引导和调试很有用。

不保证在未来的版本中会保留。

println()

println()内置函数以一种特定于实现的方式格式化其参数,并将结果写入标准错误

总是在参数之间添加空格,并添加换行符。

println()对于引导和调试很有用。

不保证在未来的版本中会保留。