7. 内置集合 - 数组
7. 内置集合 - 数组

7. 内置集合 - 数组

学到什么

  1. 什么是数组?
  1. 如何获取数组长度?
  1. 如何操作数组元素?
  1. 如何比较两个数组?
  1. 如何拷贝数组?
  1. 如何创建多维数组?
  1. 如何省略变量(补充)?

概念

数组是一个长度固定和元素类型相同的集合,类型也可以自定义。如果想保存任意类型,定义一个接口类型数组。
 
notion image
数组每个元素的位置,称为索引。第一元素索引为0,第二个为1,以此类推。

声明

声明格式: var 数组名 [长度]类型
 
举例:声明一个长度为 4,元素类型为 int 的数组。
var nums [4]int // 打印 [0 0 0 0]
声明后每个元素默认初始化为 0 ,如果是字符串数组,默认初始化为空字符串。
 

初始化

数组有多种初始化方式,一一列举说明,以下我用 := 简写方式。
 
方式一:初始化每个元素,如果超过数组长度,编译时会提示越界错误。
nums := [4]int{3, 2, 1, 4}
 
方式二:初始化部分元素,只有索引 0 和 1 被赋值,后面的元素默认为 0 。
nums := [4]int{3, 2} // 打印 [3 2 0 0]
 
方式三:使用 key/value 形式初始化指定索引元素,也可以和上面方式混合。
nums := [4]int{0: 3, 3: 4} 或 nums := [4]int{3, 3: 4} // 打印 [3 0 0 4]
 
方式四:不指定数组长度,使用 ... 让编译器自己决定数组的长度。
// 数组长度为 4 nums := [...]int{3, 2, 1, 4}

获取数组的长度

使用内置的函数 len 获取数组的长度。
len(array)
还可以用于获取切片、map、字符串、通道的长度。

数组元素操作

1. 获取元素

使用索引获取数组的元素,后面要讲的切片获取方式也是如此。
nums := [...]int{3, 2, 1, 4} fmt.Println(nums[1]) // 输出 2

2. 设置元素

当有了一个数组后,后面可以对此数组元素进行修改。
nums := [...]int{3, 2, 1, 4} nums[1] = 3 fmt.Println(nums) // 输出 [3 3 1 4]

遍历数组

使用“for 循环语句”遍历数组,上篇“流程控制”中有详细的“for 循环语句”讲解。
 
遍历数组有两种方式,第一种是“迭代计数”,第二种“for-range”,使用如下:

1. 迭代计数

nums := [...]int{3, 2, 1, 4} for i := 0; i < len(nums); i++ { fmt.Println(nums[i]) }

2. for-range

for i, v := range nums { fmt.Println("索引:", i, " 值", v) } // 输出 索引: 0 值 3 索引: 1 值 2 索引: 2 值 1 索引: 3 值 4

数组比较

两个数组是否相等要考虑两方面:
  • 数组必须是同一类型,这块指的类型不是元素类型,而是数组长度和元素类型决定数组的类型,例如: [2]int{1, 2} 它的类型是 [2]int ,不要误以为是 array
  • 数组元素相等
a := [2]int{1, 2} b := [2]int{1, 2} if a == b { print("相等") } else { print("相等") } // 输出 相等
注:如果 b 的初始化方式为 [...]int{1, 2} , a 和 b 依然是相等的,因为类型还是 [2]int

数组拷贝

在 Go 语言中,数组是值类型,也就是说在传递过程中会自动拷贝一份。
nums := [...]int{3, 2, 1, 4} numsCopy := nums numsCopy[1] = 3 fmt.Println("nums:", nums) fmt.Println("numsCopy:", numsCopy) // 输出 nums: [3 2 1 4] numsCopy: [3 3 1 4]

多维数组

为了更好的理解多维数组,现在还原一个场景。
 
现在有间教室,里面有 4 行 3 列的座位,现在让你记录每个座位学生的状态,0表示旷课、1表示请假、2表示已到场。

1. 声明

先看看多维数组如何声明。
 
二维数组格式:
var 数组名 [长度][长度]类型
三维数组格式:
var 数组名 [长度][长度][长度]类型
依次类推可以继续声明四维数组、五维数组等等。
 
继续回到上面的场景,可以确定需要一个 4 行 3 列的二维数组。
var students [4][3]int
 

3. 初始化

设置每个学生的状态,可以看出 1 行 3 列学生旷课(值为0),3 行 2列学生请假(值为1)。
students := [4][3]int{ {2, 2, 0}, {2, 2, 2}, {2, 1, 2}, {2, 2, 2}, }

4. 遍历二维数组

使用“迭代计数”方式遍历 students 数组,输出旷课的学生座位。
// collection/mult-array.go for i := 0; i < 4; i++ { for j := 0; j < 3; j++ { if students[i][j] == 0 { fmt.Printf("%d行%d列学生旷课", i+1, j+1) } } } // 输出 1行3列学生旷课
 

省略变量

在 Go 语言中,使用变量有个要求:“在函数体内,声明了变量就必须使用”。如果不想使用,就使用“下划线(_)”去省略。
 
举两个例子,省略函数返回的 b 变量和数组循环的索引 i 。
a, b := fun1() for i, v := range array { ... } // 省略后 a, _ := fun1() for _, v := range array { ... }

总结

本篇讲解了 Go 语言内置集合中的数组,还有对省略变量知识点的补充,因为太常用了。下篇将讲解切片,它和数组关系密切,所以本篇一定要掌握明白。如果遇到什么问题,就在下方留言!