数组
Go语言中数组的声明语法为[n]DataType,n表示数组长度,DataType表示数组元素的数据类型。跟c、java以及c#等语言不同,Go语言将数组长度写在类型的前面。
Go语言中数组有以下几个特性:
- 数组是固定长度,创建完不能再追加元素。
- 不同长度的数组元素类型相同也不可以直接赋值。
- 数组是值类型,赋值或作为函数实参传递时均会进行值拷贝,因此当数组长度较大时可以用slice代替。
slice
正因为数组有着上述诸多的不足之处,因此Go语言提供了另一种内置的数据类型slice(切片)。slice的定义和数组非常相似var s=[]int,区别是数组需要在[]指定长度或...,而slice[]中不需要指定长度。
slice的操作
- make()创建新的slice并追n个元素,元素的初始值为该数据类型的零值。
- append()向slice追加一个元素,并返回新的slice。
- 使用slice[n:n]产生子slice, 子slice与原slice引用同一个底层数组。
- len()返回slice的长度,实际元素的数量。
- cap()返回slice的容量,容量的大小受slice扩容机制的影响并不总等于实际元素的数量。
- copy()将源slice元素复制给目标slice。
- 可以通过for range遍历slice。
slice的结构
slice是一个结构体,源代码如下:
slice结构有三个字段:array、len以及cap。
- array字段是一个指针,指向存储实际元素的数组。
- len表示slice当前的元素数量。
- cap表示slice当前的容量。
slice作为变量赋值或函数实参传递,虽然对slice本身进行了值拷贝,但指向的底层数组还是同一个,因此函数对slice的修改也会影响到原slice,可以把slice看成是引用类型。
slice的扩容机制
slice一般按照当前容量的两倍来扩容,即1,2,4,8,16这样规律(2^n)。
slice的子切片
slice可以通过slice[n:n]方式来创建子的slice,需要注意的是子slice与原slice引用的是同一个数组,因此修改或append子slice会引起原slice的修改。
map
Go语言内置的字典类型是map,格式为map[K]T,其中K可以是任意可比较类型。map和slice一样也是引用类型。
创建map
map的操作
- 通过make函数创建map实例。
- 通过下标map[K]方式读取、新增或修改map元素。
- len()函数返回mapKV的数量。
- 可以通过for range来遍历map,但顺序不能保证。
- delete(map,K)删除元素,即使对应的Key不存在也不会引起程序错误。
map的注意事项
- 内置的map是非并发安全的,多个goroutine并发读写时会引起程序异常。标准包中的sync.Map结构体是并发安全的。
- 如果map的值是结构体类型,那么修改应采用整个值替换的方式而不是单独修改结构体的某个字段。