一.切片(Slice)
go语言中切片(Slice)和数组长的很像,可以把切片看做是对数组的一层简单的封装,在每个slice的底层数据结构中一定会包含一个数组。所以slice的功能是强大的,拥有数组的特性及slice本身所扩展的一些特性。
看下面一个例子认识下slice
arr := [...]int{0,1,2,3,4,5,6,7,8} //arr是数组 s := arr[2:6] //这里s就是一个slice
slice与数组的区别:
1. go语言数组的长度不可改变,长度定义好之后,就不能再更改了,而slice非常灵活,可以动态扩容。
2. slice 的底层数据是数组,slice是对数组的封装。
slice的声明
var identifier []type
:identifier表示变量名,type表示切片中的元素类型,切片不需要说明长度。
例如:
var a []string //声明一个字符串切片 var b = []int{} //声明一个整型切片并初始化 var c = []bool{false, true} //声明一个布尔切片并初始化
slice使用
切片定义完之后,还不能使用,因为本身还是空的,是一个nil slice,需要让其引用到一个数组,或者make一个空间供切片使用。
1. 简单切片表达式
这种就是上面第一个例子,基于数组得到切片,常见的使用方式是 identifier[low: high]
,low和high表示一个索引范围(左包含,又不包含),有点类似于php中函数substr(),可以对slice里面的元素进行截取。
2. make创建slice方式
make创建slice是这样的:make([]Type, size, cap)
, Type表示切片的元素类型,size表示slice中元素的数量,cap表示切片的容量,可以传入前面2个参数,第3个参数可以省略。
slice截取
通过从数组或者slice直接截取截取也是比较常见的一种创建 slice 的方法,可以通过设置下限索引的位置及上限索引的位置来截取切片。
arr := [...]int{0,1,2,3,4,5,6,7}
fmt.Println("arr[2:6] = ", arr[2:6])
fmt.Println("arr[:6] = ", arr[:6])
fmt.Println("arr[2:] = ", arr[2:])
fmt.Println("arr[:] = ", arr[:])
输出:
arr[2:6] = [2 3 4 5]
arr[:6] = [0 1 2 3 4 5]
arr[2:] = [2 3 4 5 6 7]
arr[:] = [0 1 2 3 4 5 6 7]
第一个:[2:6] 从索引2(闭区间:包含)开始到索引6(开区间:不包含),这中间区域的值 2 3 4 5。
第二个:[:6] 省略左索引(默认从0开始)到索引6(开区间:不包含),这段区域的值 0 1 2 3 4 5。
第三个:[2:] 省略右索引(默认最大的索引)就是从索引2(闭区间:包含)一直到最后,这段区域的值 2 3 4 5 6 7 。
第四个:[:] 省略左右索引,表示全部,展示所有的元素 0 1 2 3 4 5 6 7。
基于已有slice创建新slice,这就是reslice。
append()方法为切片添加元素
Go语言的内建函数append()
可以为切片动态添加元素,每个切片会指向一个底层数组,这个数组的容量够用就添加新增元素。当底层数组不能容纳新增的元素时,切片就会自动按照一定的策略进行“扩容”,此时该切片指向的底层数组就会更换。“扩容”操作往往发生在append()
函数调用时,所以我们通常都需要用原变量接收append函数的返回值。
func main(){
//append()添加元素和切片扩容
var numSlice []int
for i := 0; i < 10; i++ {
numSlice = append(numSlice, i)
fmt.Printf("%v len:%d cap:%d ptr:%p
", numSlice, len(numSlice), cap(numSlice), numSlice)
}
}
输出结果
[0] len:1 cap:1 ptr:0xc0420080a0
[0 1] len:2 cap:2 ptr:0xc0420080f0
[0 1 2] len:3 cap:4 ptr:0xc04200e340
[0 1 2 3] len:4 cap:4 ptr:0xc04200e340
[0 1 2 3 4] len:5 cap:8 ptr:0xc04200c200
[0 1 2 3 4 5] len:6 cap:8 ptr:0xc04200c200
[0 1 2 3 4 5 6] len:7 cap:8 ptr:0xc04200c200
[0 1 2 3 4 5 6 7] len:8 cap:8 ptr:0xc04200c200
[0 1 2 3 4 5 6 7 8] len:9 cap:16 ptr:0xc042062080
[0 1 2 3 4 5 6 7 8 9] len:10 cap:16 ptr:0xc042062080
从上面的结果可以看出:
append()
函数将元素追加到切片的最后并返回该切片。- 切片numSlice的容量按照1,2,4,8,16这样的规则自动进行扩容,每次扩容后都是扩容前的2倍。
二. 集合(Map)
Map是一种无序的键值对的集合,其内部主要使用的是hash table这种数据结构,可以通过key来快速查询数据,也可以进行增删查的操作。
map的创建
可以使用内建函数make,也可以使用map关键字来创建Map。
1. map关键字创建:var mapName map[keyType]valueType
2. make函数创建:map[KeyType]ValueType