数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。
数组声明
数组的声明语法如下:var 数组变量名 [元素数量]Type
- 数组变量名:数组声明及使用时的变量名。
- 元素数量:数组的元素数量,可以是一个表达式,但最终通过编译计算的结果必须是整型数值,元素数量不能含有到运行时才能确认大小的数值。
- Type:可以是任意基本类型,包括数组本身,类型为数组本身时,可以实现多维数组。
数组的每个元素都可以通过索引下标来访问,索引下标的范围是从 0 开始到数组长度减 1 的位置,内置函数 len() 可以返回数组中元素的个数。
func main(){
var arr [3]int // 定义三个整数的数组
fmt.Println(arr[0]) // 打印第一个元素
fmt.Println(arr[len(arr)-1]) // 打印最后一个元素
fmt.Println(arr) // [0,0,0]
}
默认情况下,数组的每个元素都会被初始化为元素类型对应的零值,对于数字类型来说就是 0。
数组初始化
- 完整写法
var arr[3]int = [3]int{1,2,3}
可省略为:var arr = [3]int{1,2,3}
- 短变量写法
arr := [3]int{1,2,3}
- 若在声明时,不确定数组长度
var arr = [...]int{1,2,3}
- 若在初始化时,只初始化个别位置的元素(通过下标),缺省部分使用默认值代替
var arr = [...]int{0:1,2:2} // [1,0,2]
初始化时需要注意:
- 若 {} 中的元素个数,小于 [] 中的数字,剩余的位置使用默认值代替
var arr = [3]int{1,2} // [1,2,0]
- {} 中的元素个数不可大于 [] 中的数字,会抛出错误
数组遍历
- 通过普通 for 循环来遍历数组
func main(){
var arr [3]int // 定义三个整数的数组
for i := 0 ; i < len(arr) ; i++{
fmt.Println(arr[i]) // 0,0,0
}
}
- 通过 for range 来遍历数组
func main(){
var arr [3]int // 定义三个整数的数组
for key,value := range arr{
fmt.Println(key,value) // 0,0,0
}
}
运行结果:
0 0
1 0
2 0
若不想接收 key 的值可以使用 _ 替换
数组类型
func main(){
var arr1 = [3]int{1,2,3}
fmt.Printf("%T",arr1) // [3]int
var arr2 = [...]int{1,2}
fmt.Printf("%T",arr2) // [2]int
fmt.Println(arr1 == arr2) // invalid operation:arr1 == arr2 (mismatched types [3]int and [2]int)
}
数组的类型是包括其长度的,两个长度不相同的数组,是无法进行比较的。当我们在比较两个数组是否相等时,会比较数组中的每一个元素,存在一对不相等的元素结果即为 false
向函数传递数组
如果你想向函数传递数组参数,你需要在函数定义时,声明形参为数组:
func myFunction(arr [num]int){
}
- arr:为数组名
- num:为数组的长度
Go 语言中的数组是值类型,在默认情况下是值传递,会进行值拷贝。
func main(){
var arr = [3]{1,2,3}
fmt.Printf("main函数中arr[0]的内存地址:%v",&arr[0])
modify(arr)
fmt.Println("main 函数:",arr)
}
func modify(arr [3]int){
fmt.Printf("modify函数中arr[0]的内存地址:%v",&arr[0])
fmt.Println("modify begin:",arr)
arr[0] = 10
fmt.Println("modify end:",arr)
}
输出结果:
main函数中arr[0]的内存地址:0xc00012a000
modify函数中arr[0]的内存地址:0xc00012a030
modify begin:[1,2,3]
modify end:[10,2,3]
main 函数:[1,2,3]
通过查看数组中第一个元素的内存地址,可以发现两个函数中数组指向的内存是不相同的。在函数传递时,会复制整个数组的值,而不是指针 / 地址。因此函数内改变的是副本的值,不会改变本身的值。
若想要在函数外部修改数组的值,可以使用引用传递(指针方式)。
func main(){
var arr = [3]{1,2,3}
fmt.Printf("main函数中arr[0]的内存地址:%v",&arr[0])
modify(&arr)
fmt.Println("main 函数:",arr)
}
func modify(arr *[3]int){
fmt.Printf("modify函数中arr[0]的内存地址:%v",&arr[0])
fmt.Println("modify begin:",arr)
arr[0] = 10
fmt.Println("modify end:",arr)
}
输出结果:
main函数中arr[0]的内存地址:0xc000018240
modify函数中arr[0]的内存地址:0xc000018240
modify begin:[1,2,3]
modify end:[10,2,3]
main 函数:[10,2,3]
此时查看两个函数第一个元素的内存地址,会发现它们是相同的,所以在 modify 函数中修改 arr[0] 的值,main 函数中的值也会修改。
二维数组
Go 语言支持多维数组,以下为常用的多维数组声明方式:
var array_name [size1][size2]...[sizen] array_type
其中,array_name 为数组的名字,array_type 为数组的类型,size1、size2 等等为数组每一维度的长度。
以二维数组为例,以下实例声明了二维的整型数组:
var arr [2][3]int
初始化二维数组:
var arr = [2][3]int{{1,2,3},{4,5,6}}