Go语言中的数组
1 数组的初始化和定义
在 Go 语言中,数组是固定长度的、同一类型的数据集合。数组中包含的每个数据项被称为数组元素,一个数组包含的元素个数被称为数组的长度。
在 Go 语言中,你可以通过 []
来标识数组类型,但需要指定长度和元素类型。以下是一些常见的数组声明方法:
var a [8]byte // 长度为8的数组,每个元素为一个字节
var b [3][3]int // 二维数组(9宫格)
var c [3][3][3]float64 // 三维数组(立体的9宫格)
var d = [3]int{1, 2, 3} // 声明时初始化
var e = new([3]string) // 通过 new 初始化
数组也可以通过 := 进行一次性声明和初始化,所有数组元素通过 {} 包裹:
array := [5]int{1,2,3,4,5}
还可以通过语法糖声明省略数组长度:
array2 := [...]int{1, 2, 3} // 编译时,Go语言会自动计算该数组的长度
数组在初始化的时候,如果没有填满,则空位会通过对应元素的零值填满:
array3 := [5]int{1,2,3}
Go语言中,数组初始化时,可以指定下标位置的元素值,未指定的位置,数据元素类型的零值填充:
a := [5]int{1:3, 3:5}
2 数组元素的访问和设置
可以使用数组下标来访问 Go 数组中的元素,数组下标默认从 0 开始,len(arr)-1
表示最后一个元素的下标:
arr := [5]int{1,2,3,4,5}
a1, a2 := arr[0], arr[len(arr) - 1]
如上数组arr,a1 的值是1,a2是数组的最后一个元素5。
访问数组元素时,下标必须在有效范围内,比如对于一个长度为5的数组,下标有效范围时 [0,4],超出这个范围编译时会报索引越界异常:
和字符串这种不可变值类型不一样,数组除了支持下标访问对应索引的元素值以外,还能够通过下标设置对应索引位置的元素值:
arr[0] = 100
3 数组元素的遍历
可以通过for循环遍历数组中所有的元素:
for i := 0; i < len(arr); i++ {
fmt.Println("Element", i, "of arr is", arr[i])
}
Go 语言还提供了一个关键字 range,也能够用于遍历数组中的元素:
for i, v := range arr {
fmt.Println("Element", i, "of arr is", v)
}
range
表达式返回两个值,第一个是数组下标索引值,第二个是索引对应数组元素值,如果只想获取元素值或者只想获取索引值可以借助匿名变量:
// 只获取索引值
for i, _ := range arr {
fmt.Println("index is ", i)
}
// 只获取元素值
for _, v := range arr {
fmt.Println("value is ", v)
}
4 多维数组
多维数组的操作与一维数组一样,只不过每个元素可能是个数组,在进行循环遍历的时候需要多层嵌套循环,下面是一个多维数组声明、初始化以及使用:
// 声明二维数组
var multi [9][9]string
// 二维数组元素赋值
for i := 0; i < 9; i++ {
for j := 0; j < 9; j++ {
m := i + 1
n := j + 1
if n > m {
// 九九乘法表
// 1*1 = 1
// 1*2 = 2 2*2 = 4
// 1*3 = 3 2*3 = 6 3*3 = 9
// 当n>m,跳出循环
continue
}
multi[i][j] = fmt.Sprintf("%d*%d=%d", n, m, m*n)
}
}
// 二维数组打印
for i := 0; i < 9; i++ {
for j := 0; j < 9; j++ {
if j > i {
continue
}
fmt.Printf(multi[i][j] + " ")
if j == i {
fmt.Println()
}
}
}
代码运行,打印的内容如下:
多维数组打印有一个优化的方法,代码如下:
// 打印九九乘法表
for _, v1 := range multi {
for _, v2 := range v1 {
fmt.Printf("%-8s", v2) // 位宽为8,左对齐
}
fmt.Println()
}
5 数组总结
Go语言中的数组类型遍历一旦声明后长度就不能再变,这样就无法动态添加元素到数组中,如果要添加一个元素到数组中,需要将就数组的元素都拷贝过来,最后添加新的元素,如果数组的长度不能确定,我们设置了一个较多元素的数组,这就会影响到程序的性能。
数组是值类型,将数组作为参数传递到函数时,传递的是数组的值拷贝,也即会先将数组拷贝到形参,函数体中引用的是形参而不是原来的数组,当我们在函数中对数组元素进行修改的时候,并不会影响原来数组的值,如果数组很大时,值拷贝也会影响到程序的性能。
因此,Go语言也有一个引用类型的、支持动态添加元素的新“数组”类型,也即切片类型。在Go语言中,实际很少使用数组,大多时间会使用切片取代数组。