数组是一个由固定长度的特定元素类型组成的序列,元素的个数可以是0, 也可以不为0。
数组的长度是固定的。
数组的声明
一维数组定义格式: var variable_name [size] variable_type
示例:
var a [3] int // 3 个整数的数组
var b [4] float32 // 长度为10,类型为float32的数组
var c [5] string // 长度为5,类型为string的数组
数组的初始化
默认情况下,数组的每个元素会被初始化为元素类型对应的零值,比如,数字对应就是0, string 对应就是空。
我们也可以显示的初始化数组。
var a [3] int = [3]int{3, 2, 1} // a = [3 2 1]
var a [3] int = [3]int{3, 2} // a = [3 2 0]
// 如果数组的长度位置出现...省略号,表明数组的长度是根据初始化值的个数来计算的
b := [...]int{3, 2, 1} // b = [3 2 1]
// 也可以指定一个索引和对应值列表的方式初始化
c := [...]int{1:-3 ,3: -2, 9:-1} // b = [0 -3 0 -2 0 0 0 0 0 -1]
访问数组元素
数组元素可以通过索引来读取, 索引范围从0到数组长度减1。函数 len()
返回数组中元素的个数。
int x = c[3] // x = -2
int lengthOfc = len(c) // lengthOfc = 10, 就是数组c的长度了
// 遍历数组, 打印索引和对应的元素到屏幕上
for i, v := range b {
fmt.Println(i, v)
}
// 遍历数组,打印数组元素到屏幕上,不打印索引
for _, v := range b {
fmt.Printf(v)
}
数组的比较
当两个数组的所有元素都相等时,数组才是相等的。
var a [3] int = [3]int{3, 2, 1}
b := [...]int{3, 2, 1}
fmt.Println(a == b) // true
数组的类型是存储的元素的类型加上数组的长度,所以 [2]int
和 [3]int
是两种不同的类型。
二维数组
多维数组声明格式:
var variable_name [size1][size2]...[sizeN] variable_type
示例:声明三维数组
var a [3][4][5]int // 3维整型数组
多维数组是通过构造数组的数组来实现的。
初始化二维数组
a := [3][4]int {
{1, 2, 3, 4},
{2, 3, 4, 5},
{4, 5, 6, 7},
} // 第一行索引为 0, 第二行索引为1, 第三行索引为2
访问二维数组
int x = a[2][3] // x = 7
int length = len(a) // length = 3
int length1 = len(a[0]) // length1 = 4
// 可以用循环嵌套来遍历二维数组
for _, v := range a {
for _, x := range v {
fmt.Print(x, " ")
}
fmt.Println()
}
/* output
1 2 3 4
2 3 4 5
4 5 6 7
*/
数组作为函数参数
当函数接收一个数组作为参数时,函数参数接收的是一个复制的副本,并不是原始的变量,对数组参数的任何修改都发生在复制的数组上,并不直接修改原始的数组变量。
如果我们显式地传入一个数组指针,那么通过指针对数组的任何修改都直接发生在原始的数组上。这一点与C语言是一致的。
// 下面的函数将传入的数组清零
func zero(ptr *[]int) {
for i := range ptr {
ptr[i] = 0
}
}
总结
因为数组的长度是固定的,因此很少直接使用数组。
和数组对应的是 slice (切片),它长度可变,功能灵活,我们一般使用slice来代替数组。