go语言中,数组的使用频率并不高,因为其长度不可变,所以很多时候都是使用slice。slice比数组更灵活,其长度是可变的,不过在介绍slice之前,还是要先介绍一下数组
var a [3]int 第一种方式就是定义了一个程度位3的int数组,里面的元素都是默认值0
var b [3] int = [3] int {1,2,3} 定义数组的同时进行初始化的赋值,这种定义方式有些冗余,精简操作就是把比变量b后面的[3]int取消, var b =[3]int {1,2,3}
c := […]int{1,2,3} 省略了数组程度,其程度由后面的初始化值的程度确定
d := […]int{4,4:1,1:2} 可以看到后面并没有给所有的元素赋值,而且赋值使用了index:value,比如4:1的意思就是下标为4的元素赋值1,这时候数组长度根据出现的最大下标确定,因为定义时没有指定,所以此时数组长度4.[4 2 0 0 1]
go语言中,[3]int [4]int是两种不同的数组类型,这两种不同的数组类型是在编译时就已经确定的。把[4]int赋值给[3]int的变量会报错,因为go语言的数组的一部分,并非其他语言那这样只存储数组开始的地址
在分配内存底层空间的时候,数组的元素是紧挨着分配到固定位置的,这也是数组长度不可变的原因。
b := &a 定义了一个指向数组a的指针b, 通过b也可以访问数组a内的元素
for forr 都可以处理string的遍历,但是更推荐forr 也就是range,因为for range的方式不会出现数组下标越界的问题
数组的元素可以是基本的数据类型,也可以是接口,结构体等,这些数据结构后面介绍
也可以定义0个元素的数组
var d [0] int
在使用数组时一定要注意,go语言的数组是传递值的,而通常其他数组都是传递引用的。否则函数形参接收到的数组其实是完全复制了一份,不仅浪费性能,而且对于形参数组的修改不会影响原数组。
slice
slice切片是一个拥有相同类型元素的可变长序列,且slice的定义与数组的定义非常像,它就是没有长度的数组。
对于slice的结构体,reflect.SliceHeader的定义如下:
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
可以看到,slice有三个属性,指针,长度,容量。指针指向slice开始访问的第一个元素,长度是切片的长度,容量是指从slice开始访问的第一个元素到底层数组最后一个元素的个数。slice长度不可以超过slice容量
切片的底层是数组,golang的slice对应着底层数组,一个底层数组可以对应多个slice
首先来了解一下slice的定义 s := [] int {1,2,3,4,5}如果在[]中指定了长度或者写入了省略号,那么这就是一个数组如果只是想创建一个slice而不赋值,那么可以使用make函数进行操作。
ss := make ([]int,10)通过make函数定义了[]int类型的切片,长度为10。定义时可以设定第三个参数caps ,也可以空值,ss的caps为10,对于数组元素,由于没有设定具体的初始值,因此元素都会取对应元素类型int的初始默认是0
forr遍历slice ss
for i ,v := range ss {
fmt.println(i,v)
}
如果想主动释放slice的空间,可以通过为它赋值nil实现ss = nil