Builtin 模块
最近在学Go,但感觉标准库中文资料不是很多,直接看官网文档又没有循序渐进的过程,所以自己在边看边记录,如有谬误还请指出,感谢。
这部分总结了Go中内置的模块,不需要导包。
来自Go的标准文档,版本是1.21.4。
在类型方面是我自己的总结和理解。
每篇一首歌
类型(types)
Go语言提供的类型
首先,Go语言内置了多种类型,我这里将其分为两类:值类型和引用类型。
并不是说值类型就分配在栈上,引用类型就分配在堆上,Go中的变量分配的位置会由Go编译器自动评估,如果可以就在栈上分配,如果要传出指针则会分配在堆上。
我这里说得值类型和引用类型的区别是当该类型的值作为函数参数时,对于该类型的修改不会传播到函数之外,值类型的影响局限于函数内,而引用类型则传递到函数之外。另外,引用类型可以被赋值为nil
,而值类型则不行。
Go内置的值类型(在x64平台上)如下:
类型名 | 大小 |
---|---|
(u)int |
1 word |
intN (N=8,16,32,64) |
N/8 bytes |
uintN (N=8,16,32,64) |
N/8 bytes |
uintptr |
8 bytes |
floatN (N=32,64) |
N/8 bytes |
complexN (N=64,128) |
N/8 bytes |
bool |
1 byte |
[N]Type |
N*sizeof(Type) |
string |
16 byte |
需要注意的是,数组类型是值类型,其大小也是数组中所有元素的数量之和。string
是不可变的类型,所以其传值、获取字串的操作是非常高效的。
Go内置的引用类型(在x64平台上)如下:
类型名 | 大小 |
---|---|
slice |
24 btes |
map |
8 bytes |
chan |
8 bytes |
函数类型 | 8 bytes |
interface |
16 bytes |
slice
中包含指向元素的指针、长度、容量。interface
包含真实类型和指向其引用的值的指针。
需要注意的是,等于nil
的interface
和其引用的值为nil
的interface
是不一样的,要注意区分。
验证代码:
1 | func GetValueTypeSize() { |
别名数据类型
Go还设置了基本数据类型的别名:
1 | type byte = uint8 |
接口(interface)
内置模块还默认定义了几个接口:
1 | type error interface { |
comparable
接口默认被所有可比较的类型(booleans, numbers, strings, pointers, channels, arrays of comparable types, structs whose fields are all comparable types)实现了。具体可见这里。
函数
本文档中使用了以下仅用于解释的类型,这些类型均非实际存在:
类型 | 说明 |
---|---|
ComplexType |
表示一种复数类型:complex64 或complex128 |
FloatType |
表示一种浮点类型:float32 或float64 |
IntegerType |
表示一种整型:int , uint , int8 等 |
Type |
表示任意一种Go的类型,但在一个函数调用中表示相同类型 |
Type1 |
表示任意一种Go的类型,但在一个函数调用中表示相同类型 |
内置函数
append
1 | func append(slice []Type, elems ...Type) []Type |
向一个slice
中添加元素,并返回添加元素后的slice
。注意,若原slice
的capacity无法放得下要添加的元素,则会申请新的空间以存放元素,所以应该将append
的返回值重新赋值给slice
。
作为例外,string可以被添加到byte的slice里。
例子:
1 | slice = append(slice, elem1, elem2) |
cap
1 | func cap(v Type) int |
获取v的容量:
类型 | 结果 |
---|---|
数组 | 数组v中元素的数量,等于len(v) |
指向数组的指针 | *v中元素的数量,等于len(*v) |
slice | append时无需realloc而可以直接append时,最大的append后元素数量;等于nil 时返回0 |
chan | 通道的缓冲区容量,单位是元素的个数,如果v等于nil ,返回0 |
len
1 | func len(v Type) int |
获取v的长度。
类型 | 结果 |
---|---|
数组 | 数组v中元素的数量 |
指向数组的指针 | *v中元素的数量,即便v等于nil |
slice | v中元素的数量,v等于nil 时返回0 |
string | v中的字节数 |
chan | 缓冲队列中未读的元素的数量,v等于nil 时返回0 |
new
1 | func new(Type) *Type |
这个函数会分配内存。第一个参数是一个类型,而不是值。返回值是一个指针,该指针指向该类型的零值。
make
1 | func make(t Type, size ...IntegerType) Type |
为slice/map/chan分配内存并初始化。和new一样,make第一个参数也是一个类型。和new不同的是,函数的返回值是该类型的值,而非指针。
类型 | 其他参数 |
---|---|
slice | 如果有一个参数,那么该参数表示slice的长度和容量;如果有两个参数,那么第一个参数表示长度,第二个参数表示容量(容量>=长度) |
map | 能容纳指定数量元素的map,如果填则初始化为一个较小值 |
chan | 通道的缓冲区大小,0或者不填表示无缓冲 |
clear
1 | func clear[T ~[]Type | ~map[Type]Type1](t T) |
参数必须是slice、map或者两种类型的指针。slice会将length清零,map会清空此map。
close
1 | func close(c chan<- Type) |
参数是双向的通道或者发送方的通道。作用是当最后一个元素从c中读出后关闭该通道。当最后一个元素从c中读出后,读取方再从通道中读取数据时会立刻非阻塞地返回,返回值时该通道中传递的数据类型的零值,如果接收者的形式为:
1 | val, ok := <- c |
则ok
的值为false
。
delete
1 | func delete(m map[Type]Type1, key Type) |
从map中删除键值为key的那一项。如果m为nil
,或者map中没有该key,则无操作。
copy
1 | func copy(dst, src []Type) int |
把元素从slice
src复制到slice
dst(特例:也可以把从string中拷贝字节到[]byte)。源slice和目的slice可以重叠。返回值是复制的元素的数量,为len(src)和len(dst)的较小值。
complex
1 | func complex(r, i FloatType) ComplexType |
生成一个复数,r表示实部,i表示虚部。r和i必须类型相同,同时是float23
或同时是float64
(或者可以赋值给他们),float32
对应返回值为complex64
,float64
为complex128
.
real
1 | func real(c ComplexType) FloatType |
返回复数的实部。
imag
1 | func imag(c ComplexType) FloatType |
返回复数的虚部。
min, max
1 | func min[T cmp.Ordered](x T, y ...T) T |
返回课比较类型的最小/大值,最少有两个参数。如果T是浮点类型且有一个是NaN,那么返回值会是NaN。
print, println
1 | func print(args ...Type) |
将输出写入到标准错误
panic, recover
1 | func panic(v any) |
出错和恢复,这里就不介绍了。
常量
1 | const ( |
变量
1 | var nil Type // Type must be a pointer, channel, func, interface, map, or slice type |