Go之数组与切片

2019-06-13  本文已影响0人  authetic_x

数组

由固定长度的特定类型元素组成的序列,一个数组可由零或多个元素组成。默认情况下,数组的每个元素都被初始化为元素类型对应的零值。

初始化

var a = [3]int{1,2,3}
// 省略号表示数组的长度根据初始化值的个数来计算
var b = [...]int{1,2,3}
var c = [2]int{1,2}

a == c  // compile error

数组长度是数组类型的一个组成部分,因此 [3]int 和 [2]int 是两个不同的类型。数组的长度必须是常量表达式,因为数组的长度需要在编译阶段确定。

如果数组的元素类型是可以相互比较的,那么数组类型也是可以相互比较的

参数传递

func reverse1(a [3]int) {
    a[0], a[2] = a[2], a[0]
}

func reverse2(a *[3]int) {
    a[0], a[2] = a[2], a[0]
}

func main() {
    a := [3]int{1,2,3}
    reverse1(a)
    fmt.Println(a)  // [1 2 3]

    reverse2(&a)
    fmt.Println(a)  // [3 2 1]
}

从中可以看出,数组是一个值类型,将数组作为参数直接传递给函数只会复制数组的一个副本,这一点和 C 不同。

由于数组长度固定,是一个僵化类型,所以在Go语言中我们很少使用数组,更多的是用切片

Slice

Slice 代表变长的序列,序列中每个元素都有相同的类型。slice 是一个轻量级的数据结构,底层引用一个数组对象,一个 slice 由三个部分构成:指针、长度和容量。指针指向第一个 slice 元素对应底层数组的地址,长度对应 slice 元素的数目,容量一般是从 slice 开始位置到底层数据的结尾位置。

初始化

var array = [5]int{1,2,3,4,5}

var a = array[:]
var b = []int{1,2,3}
var c = []int(nil)  // c == nil, true
// 容量可省略,默认等于长度
var d = make([]int, 5)[:]
var e = make([]int, 5, 10)

slice 不可比较,唯一合法的是和 nil 比较,注意就算 slice 的长度和容量都为空,slice 也不一定为 nil,如var s = []int{}

append

用于向切片的末尾追加元素,当容量不足时,Go会采用一定的策略自动扩容,可以同时添加多个元素或切片

var s []int
s = append(s, 1, 2, 3)
var q []int
q = append(q, s...)

新的切片可能还会引用原来的底层数组,也可能会引用一个新创建的底层数组,取决于Go的内存策略

上一篇 下一篇

猜你喜欢

热点阅读