golang中数组的定义形如[length]type,其中num表示数组的长度,是个非负数。type代表数组中的元素类型,可以是int、bool等基本类型,也可以是自定义的类型,数组中所有元素的类型是相同的,且数组的长度也是数组类型的一部分。
下面是一些数组的定义方式:
// 定义一个长度为5的元素为int类型的数组
var a [5]int
// 定义一个长度为5的元素为int类型的数组
var b [8]bool
当我们在数组定义时就已经有了数据的情况下可以直接省略数组的长度,形式如下:
// 定义了一个包含三个元素的数组
var c = [...]int{1,2,4}
此外golang中还支持切片类型,其是对数组的引用,形如[]type。
下面是切片的定义方式:
// 定义一个元素类型为int的切片
var a []int
// 效果同上
var b = make([]int, 0)
// 定义一个长度为0,容量为10的int类型切片
var c = make([]int, 0, 10)
对切片的追加操作使用append函数,如:
var a []int
// 向切片中追加一个元素
a = append(a, 1)
var b [] int
// 向切片中追加另一个相同类型的切片
a = append(a, b...)
需要注意的是:由于切片是引用类型,其元素存储在底层指向的数组中,当向切片中添加的数据超出其容量大小时会发生扩容,申请一个新的数组并指向它,因此我们在对切片进行操作的时候要额外注意这种扩容可能带来的影响。
举个例子:
package main
import "fmt"
func main() {
var a []int
increase(a)
fmt.Println(a)
}
func increase(a []int) {
for i := 0; i < 100; i++ {
a = append(a, i)
}
}
上面的代码并不会打印出[0 1 ... 99]。
package main
import "fmt"
func main() {
var a = []int{1, 2, 3}
b := a
a[2] = 4
fmt.Println(b)
a = append(a, []int{5, 6, 7, 8}...)
fmt.Println(b)
}
上面的第一个print会打印出[1 2 4],是因为a和b共同指向了同一个底层数组,修改a[2]的值就是修改底层数组的值,因此会影响到b;第二个print还是会打印出[1 2 4],因为append导致a发生扩容,底层指向了新申请的数组,因此只影响了a。初学者需要注意这个问题。