在Go语言中,数组长度在定义后就不可更改,在声明时长度可以为一个常量或者一个常量表达式(常量表达式是指在编译期即可计算结果的表达式)。数组的长度是该数组类型的一个内置常量,可以用Go语言的内置函数len()来获取。
数组的长度在定义后无法再次修改;数组是值类型,每次传递都产生一份副本。
初看起来数组切片就像一个指向数组的指针,实际上它拥有自己的数据结构,而不仅仅是一个指针。数组切片的数据结构可以抽象为以下3个变量:
- 一个指向原生数组的指针
- 数组切片中元素的个数
- 数组切片已分配的存储空间
从底层实现的角度看,数组切片实际上仍然使用数组来管理元素,基于数组,数组切片添加了一系列管理功能,可以随时动态扩充存放空间,并且可以被随意传递,而不会导致所管理的元素被复制。
下面用 reflect 包来反射出数据的类型。
package main
import(
"fmt"
"reflect"
)
func main(){
vs:=[]interface{}{
[]int{},// slice 切片
[]int{1,2,3},// slice 切片
[]int{1,2,3}[:],//切片再切还是切片
make([]int,3,10),//标准的slice 定义方式
[3]int{1,2,3},//array 数组,确定数组长度
[...]int{1,2,3},//array 数组,由编译器自动计算数组长度。
}
for i,v:=range vs{
rv:=reflect.ValueOf(v)//进入疯狂的reflect世界
fmt.Println(i,rv.Kind())
}
}
上述程序执行结果:
0 slice
1 slice
2 slice
3 slice
4 array
5 array
注意slice和数组在声明时的区别:声明数组时,方括号内写明了数组的长度或使用...自动计算长度,而声明slice时,方括号内没有任何字符。
数组切片的扩容:
ww:=make([]int,3,5)
ww[0]=23
ww[1]=23
ww[2]=23
//ww[3]=34// 这样赋值会报错误 panic: runtime error: index out of range 超过了切片的大小
fmt.Println(cap(ww))
ww=append(ww,2,4,34)//需要用 append 给赋值, append 在存储空间不足时,会自动增加存储空间
fmt.Println(cap(ww))
fmt.Println(ww)
注:append函数会改变slice所引用的数组的内容,从而影响到引用同一数组的其它slice。 但当slice中没有剩余空间(即(cap-len) == 0)时,此时将动态分配新的数组空间。返回的slice数组指针将指向这个空间,而原数组的内容将保持不变;其它引用此数组的slice则不受影响。
参考:
数组(Array)和切片(Slice)
http://my.oschina.net/lxpan/blog/87432
Golang Go语言Array数组与Slice切片的不同
http://kejibo.com/golang-slice-array-reflect/
2.2 Go基础
https://github.com/astaxie/build-web-application-with-golang/blob/master/02.2.md
有疑问加站长微信联系(非本文作者)