Go 中数组的长度是不可改变的,而 Slice 解决的就是对不定长数组的需求。他们的区别主要有两点。

区别一:初始化方式

数组:

a := [3]int{1,2,3} //指定长度
//or
a := [...]int{1,2,3} //不指定长度

切片:

s := make([]int, 3) //指定长度
//or
s := []int{1,2,3} //不指定长度

注意 1
虽然数组在初始化时也可以不指定长度,但 Go 语言会根据数组中元素个数自动设置数组长度,并且不可改变。切片通过 append 方法增加元素:

s := []int{1,2,3} //s = {1,2,3}
s = append(s, 4) //s = {1,2,3,4}

如果将 append 用在数组上,你将会收到报错:first argument to append must be slice。

注意 2
切片不只有长度(len)的概念,同时还有容量(cap)的概念。因此切片其实还有一个指定长度和容量的初始化方式:

s := make([]int, 3, 5)

这就初始化了一个长度为3,容量为5的切片。
此外,切片还可以从一个数组中初始化(可应用于如何将数组转换成切片):

a := [3]int{1,2,3}
s := a[:]

上述例子通过数组 a 初始化了一个切片 s。

区别二:函数传递

当切片和数组作为参数在函数(func)中传递时,数组传递的是值,而切片传递的是指针。因此当传入的切片在函数中被改变时,函数外的切片也会同时改变。相同的情况,函数外的数组则不会发生任何变化。