数组
数组是同一类型元素的集合,Go语言中数组不允许混合不同类型的元素,例如包含字符串和整数的数组(除非是interface{}类型的数组,那么就可以包含任意类型)。
数组的声明
一个数组的表现形式为[n]T
。n表示数组中元素的数量,T代表每个元素的类型。注意:元素的数量n
也是该类型的一部分,因此[5]int
和[25]int
是不同的类型。数组声明后不能再调整大小。
声明数组的几种方式:
- 方式1:
var a [3]int
,声明了一个长度为3的整型数组,数组中的所有元素都被自动赋值为数组类型的零值; - 方式2:
a := [3]int{12, 34, 56}
,这里使用了简略声明,在简略声明中,不需要将数组中所有的元素赋值,例如a := [3]int{12}
,这里声明了一个长度为3的数组,但只提供了一个值12,剩下的2个元素自动赋值为0; - 方式3:
a := [...]int{12, 34, 56}
,这里忽略声明数组的长度,并用...
代替,编译器会自动计算长度。
数组是值类型
Go中的数组是值类型而不是引用类型。这意味着:
- 当数组赋值给一个新变量时,该变量会得到原始数组的一个副本,如果对新变量进行更改,则不会影响原始数组;
- 同样,当数组作为参数传递给函数时,它们是按值传递,而原始数组保持不变。
数组的遍历
假设有这样一个数组:a := [...]float64{67.7, 89.9, 21, 78}
,传统的遍历方法为:
for i := 0; i < len(a); i++ {
fmt.Printf("%d the element of a is %.2f\n", i, a[i])
}
Go提供了一种更好、更简洁的方法:使用range
迭代数组,range返回索引和该索引处的值,如果只需要索引或值,可以通过空白标识符_
来忽略其中一个。
for i, v := range a {
fmt.Printf("%d the element of a is %.2f\n", i, v)
}
切片(Slice)
切片是由数组建立的一种方便、灵活且功能强大的包装。切片本身不拥有任何数据,它们只是对现有数组的引用。带有T类型元素的切片由[]T
表示。
切片的创建
创建Slice的几种方式:
- 使用语法
a[start:end]
创建一个从a
数组索引start
开始到end-1
结束的切片; s := []int{6, 7, 8}
创建一个有3个整型元素的数组,并返回一个存储在s中的切片引用;- 使用make创建一个切片:
func make([]T, len, cap) []T
。其中容量cap
选项是可选参数,默认值为切片长度。make函数创建一个数组,并返回引用该数组的切片。
切片的修改
切片自己不拥有任何数据。它只是底层数组的一种表示。对切片所做的任何修改都会反应在底层数组中。当多个切片共用相同的底层数组时,每个切片所做的更改将反映在数组中。
切片的长度和容量
切片的长度是切片中的元素数,切片的容量是从创建切片索引开始的底层数组中元素数。
func main() {
ary := [...]int{11, 22, 33, 44, 55, 66, 77}
slice := ary[1:3]
// Output: length of slice 2 capacity 6
fmt.Printf("length of slice %d capacity %d\n", len(slice), cap(slice))
}
追加切片元素
使用append
函数可以将新元素追加到切片上,append函数的定义是func append(s []T, x ...T) []T
。切片类型的零值为nil
。一个nil
切片的长度和容量为0。可以使用append函数将值追加到nil切片:
var names []string
names = append(names, "John", "Vinay", "Michael")
也可以使用...
运算符将一个切片添加到另一个切片:
a := []int{1, 2, 3, 4}
b := []int{5, 6, 7}
s := append(a, b...)
切片的函数传递
可以认为,切片在内部由一个结构体类型表示,包含长度、容量和指向数组第零个元素的指针。当切片传递给函数时,即使它通过值传递,指针变量也将引用相同的底层数组。因此,当切片作为参数传递给函数时,函数内所做的更改也会在函数外可见。
内存优化
切片持有对底层数组的引用。只要切片在内存中,数组就不能被垃圾回收。在内存管理方面,这是需要注意的。 假设有一个非常大的数组,但我们只想处理它的一小部分,一种好的方式是创建一个新的slice,然后使用copy函数来生成一个待处理切片的副本,这样原始数组就可以被垃圾回收了。
reference: