Go 的数组

91 阅读3分钟

「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。

概念

  • 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列
  • 可以是任意的原始类型,例如:整型、字符串或者自定义类型
  • 数组元素可以通过下标(索引)来读取、修改
  • 数组的下标(索引)取值范围是从 0 开始,到长度减 1
  • 数组一旦定义后,大小不能更改,因为数组的大小是类型的一部分,所以[10]int[20]int类型是不同的

语法格式

var variable_name [SIZE] variable_type

声明的🌰

package main

import "fmt"

func main() {
	// 指定长度
	var arr1 [3]int

	// 二维数组
	var arr2 [3][2]int

	// 不指定长度,Go 语言会在编译期间通过源代码推导数组的大小
	var arr3 = [...]int{2, 4, 6, 8, 10}

	fmt.Println(arr1, arr2, arr3)

	// 简短声明
	arr4 := [3]int{1, 2, 3}
	fmt.Println(arr4)
}

运行结果

[0 0 0] [[0 0] [0 0] [0 0]] [2 4 6 8 10]
[1 2 3]

数字零值是 0

注意

var arr = []int这样并不是数组,而是后面会讲到的切片

字符串数组的🌰

package main

import "fmt"

func main() {
	var strs1 [2]string
	var strs2 = [5]string{"ruby", "王二狗", "rose"}
	fmt.Println(strs1, strs2)
}

运行结果

[ ] [ruby 王二狗 rose  ]
  • 字符串零值是空字符串
  • strs2 数组长度为 5,但只提供了 3 个默认值,所以剩下的两个值会取字符串零值

内存中的数组

[4]int对应内存中四个连续的整数

获取数组的长度和容量

  • len():获取长度
  • cap():获取容量
package main

import "fmt"

func main() {
	a := [...]float64{67.7, 89.8, 21, 78}
	fmt.Printf("length:%v,caps:%v", len(a), cap(a))
}

运行结果

length4,caps:4

对于数组来说,容量和长度会一致,因为没有赋值的下标会自动取零值,在后面讲到切片、map 的时候就可能不一样了

数组的长度不能修改

package main

import "fmt"

func main() {
	// 长度不能修改
	var strs3 [2]string
	strs3[0] = "a"
	strs3[1] = "b"
	fmt.Println(strs3, strs3[0], strs3[1])

	strs3[2] = "b"
}

运行结果

会报错,提示索引 2 超出数组范围

./prog.go:12:7: invalid array index 2 (out of bounds for 2-element array)

遍历数组

普通的 for 循环

package main

import "fmt"

func main() {
	var arr3 = [...]int{2, 4, 6, 8, 10}

	// 遍历数组
	for i := 0; i < len(arr3); i++ {
		fmt.Println(i)
	}
}

运行结果

0
1
2
3
4

range

也可以使用 range 来遍历数组,具体 range 的使用可看

此处为语雀内容卡片,点击链接查看:www.yuque.com/jintianhuin…

数组是值类型

  • [10]int 和 [20]int 是不同类型,因为长度不一样
  • [5]int 和 []int 是不同类型,因为后者不是数组而是切片

数组是值传递

package main

import "fmt"

func changeArray(arr [5]int) {
	arr[0] = 100
	arr[4] = 200
}

func main() {
	// 值传递
	var arr3 = [...]int{2, 4, 6, 8, 10}
	fmt.Println(arr3)

	changeArray(arr3)
	fmt.Println(arr3)
}

运行结果

[2 4 6 8 10]
[2 4 6 8 10]
  • 前面有讲到值传递是拷贝,这里调用func changeArray(arr [5]int)会拷贝数组,将变量 arr3 拷贝给了 arr 参数,所以修改 arr 的值并不会影响变量 arr3
  • 指针的学习:www.yuque.com/go/doc/6136…

使用指向数组的指针

package main

import "fmt"

// *[5]int 是数组指针
func changeArray(arr *[5]int) {
	arr[0] = 100
	arr[4] = 200
}

func main() {
	// 值传递
	var arr3 = [...]int{2, 4, 6, 8, 10}
	fmt.Println(arr3)

	changeArray(&arr3)
	fmt.Println(arr3)
}

运行结果

[2 4 6 8 10]
[100 4 6 8 200]

这样就是指针传递,修改参数 arr 同步也会修改变量 arr3 的值

总结

一般不直接使用数组,因为要指定长度,不够灵活