赞
踩
make函数用于初始化slice、chan和map
如果只用var声明,不用make初始化,变量对应的值为nil。
1.make初始化slice
共有三个参数:类型,长度和容量,其中类型和长度必须指定。
关于长度和容量,指定长度len,即为slice赋指定长度的默认值,比如int赋值0,string赋值"",bool赋值false等。并且0到len-1都是合法的下标访问范围。
容量表示slice底层数组的长度,当使用append操作进行追加时,如果追加后的底层数组长度大于了当前容量cap,那么就会重新分配另一块连续内存给当前的底层数组,并把之前的复制过来。若不声明容量,则默认容量等于当前长度len。
切片是基于数组的。可以把切片简单的理解为数组中的一段,它保留了指向数组中某个元素(可以不是第一个元素)的指针,以及它本身的长度(也就是切片的大小)。
var s=make([]int,0,10)这条语句创建了一个长度为10的数组,并在该数组之上建立了一个切片s,该切片保留指向数组第一个元素的指针,以及它的长度(0)。
下面是demo示例:
//s的地址0xc0002fe000 s:[0 0 0 0 0], len:5,cap:6,底层数组长度为5,最大连续长度为6,返回一个[0:5]的切片 s:=make([]int,5,6) fmt.Printf("%p\n",s) fmt.Println(s) fmt.Println(len(s),cap(s)) //b的地址0xc0002fe000 s不变,append到切片s的下一位(底层数组第6位) len:6,cap:6,底层数组长度为6,返回一个[0:6]的切片 b:=append(s,6) fmt.Printf("%p\n",b) fmt.Println(b) fmt.Println(len(b),cap(b)) //c的地址0xc0002fe000 s不变,append到切片s的下一位(底层数组第6位) len:6,cap:6,底层数组长度为6,返回一个[0:6]的切片 c:=append(s,7) fmt.Printf("%p\n",c) fmt.Println(c) fmt.Println(len(c),cap(c)) //切片b[0:6],超过底层数组的cap,所以在b后面追加一个元素底层数组会进行扩容,扩容后cap的为原来的两倍,并且底层数组的首地址改变,返回一个[0:7]切片 d:=append(b,7) fmt.Printf("%p\n",d) fmt.Println(d) fmt.Println(len(d),cap(d)) //切片s根本没有变过,因为它引用的底层数组[0:5]没有变过 fmt.Printf("%p\n",s) fmt.Println(s) fmt.Println(len(s),cap(s))
打印结果:
0xc00002a0f0
[0 0 0 0 0]
5 6
0xc00002a0f0
[0 0 0 0 0 6]
6 6
0xc00002a0f0
[0 0 0 0 0 7]
6 6
0xc000092060
[0 0 0 0 0 7 7]
7 12
0xc00002a0f0
[0 0 0 0 0]
5 6
2.make初始化map
make初始化map时,可以指定map的容量,也可以不指定。而且可以看到指定map的容量对map的初始大小是没有什么关系的。
m:=make(map[string]int)
m1:=make(map[string]int,2)
fmt.Println(m,len(m)) //map[] 0
fmt.Println(m1,len(m1)) //map[] 0
可以看到map的大小随着添加的kv对增多而变大
m1:=make(map[string]int,2)
fmt.Println(m1,len(m1)) //map[] 0
m1["1"]=1
fmt.Println(m1,len(m1)) //map[1:1] 1
m1["2"]=2
fmt.Println(m1,len(m1)) //map[1:1 2:2] 2
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。