Go语言数组 | 青训营笔记

95 阅读4分钟

数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成。

数组声明

数组的声明语法如下: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。

数组初始化

  1. 完整写法
var arr[3]int = [3]int{1,2,3}   

可省略为:var arr = [3]int{1,2,3}

  1. 短变量写法
arr := [3]int{1,2,3}
  1. 若在声明时,不确定数组长度
var arr = [...]int{1,2,3} 
  1. 若在初始化时,只初始化个别位置的元素(通过下标),缺省部分使用默认值代替
var arr = [...]int{0:1,2:2} // [1,0,2]

初始化时需要注意:

  • 若 {} 中的元素个数,小于 [] 中的数字,剩余的位置使用默认值代替
var arr = [3]int{1,2} // [1,2,0]
  • {} 中的元素个数不可大于 [] 中的数字,会抛出错误

数组遍历

  1. 通过普通 for 循环来遍历数组
func main(){
    var arr [3]int             // 定义三个整数的数组
    for i := 0 ; i < len(arr) ; i++{
        fmt.Println(arr[i]) // 0,0,0
    }
}
  1. 通过 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}}