认识 Go 语言中的数组
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列。
声明方式
在 Go 语言中,数组的声明方式为 var identifier [len]type
。
声明时没有指定数组的初始化值,因此所有的元素都会被自动初始化为默认值 0。
// 声明一个数组 |
Go 语言中的数组是值类型,因此还可以用 new
来创建:
var a2 = new([5]int) |
new
返回类型的指针,因此 a1
与 a2
的区别在于:a1
的类型为 [5]int
,a2
的类型为 *[5]int
。
初始化方法
我们通过在 {}
中填写初始化值来初始化数组。
指明数组长度
指明数组的长度 len
,然后在 {}
中填写初始化值,这些值会按下标从小到大的顺序分配。
初始化值的个数不允许超过长度 len
。当初始化值的个数小于 len
时,未被初始化的位置等于默认值 0。
// 数组长度为 5,初始化了前两个数,未初始化的位是 0 |
也可以使用 {index1: a, index2: b}
的方式初始化数组,指明数组的索引和对应的下标值,未指明的下标所在位置的值等于默认值 0:
// 通过数组索引初始化 |
暗示数组长度
初始化时你也可以不直接指明数组的长度,而是使用 [...]
代替。和指明数组长度时相同,此时也可以使用顺序填写和指定索引两种方式来初始化数组。
当使用 {a, b, c}
方式传递初始化值时,Go 语言将通过初始化元素的个数来确定数组的长度:
// 通过传递初始化值确定数组长度 |
若通过指明数组的索引和对应的值来初始化数组,此时数组的长度就等于 最大索引数 + 1
:
// 最大索引是 9,所以数组的长度为 10 |
数组的遍历
在 Go 语言中使用 for ... range
遍历数组:
// i 是数组索引 |
数组是值类型
和 C/C++ 不同,Go 语言的数组是值类型的。这样一来,赋值和传参都会复制整个数组,而不是指针。
我们初始化一个数组 a
,并把它赋值给数组 b
,然后打印两者的值与指针:
a := [5]int{1, 2, 3, 4, 5} |
可以看到,两者的值是相同的,但是内存地址却不同,说明在赋值的过程中复制了整个数组。
我们再来看一下传参的例子。
定义一个函数 transmitA
,把刚才我们初始化的数组 a
传入:
func main() { |
从输出可以看出,两者的值依然相同,内存地址却是不同的。这说明在传参时数组也被复制了。
数组指针与指针数组
数组指针与指针数组听起来似乎有点拗口,那么来展开说明一下:
- 数组指针:(指向)数组(的)指针
- 指针数组:(装满了)指针(的)数组
也就是说,数组指针是个指针,它指向一个数组;而指针数组是个数组,它里面装满了指针。
数组指针
声明一个数组 a
,然后将它的地址赋值给 arrayPointer
。这样一来,arrayPointer
就是一个指向数组 a
的指针,即数组指针,它的类型为 *[5]int
。
a := [5]int{1, 2, 3, 4, 5} |
指针数组
初始化数组 pointerArray
,传入的初始化值为整型 m
与 n
的内存地址(&m
和 &n
),那么 pointerArray
就是一个装着 int
类型指针的数组,即指针数组,它的类型为 [2]*int
。
m := 1 |
总结
- 数组的长度是固定的,初始化时需要「明示」或「暗示」数组的长度
- 数组的长度是数组类型的组成部分,
[2]int
与[100]int
是不同类型的数组 - 使用
for ... range
遍历数组 - 在 Go 语言中,数组是值类型,赋值和传递参数都会发生数组的复制
- 数组指针是一个指针,它指向了一个数组
- 指针数组是一个数组,它里面装着指针
参考资料
- 本文链接:http://jalan.space/2019/11/21/2019/go-array/
- 版权声明:本博客所有文章除特别声明外,均采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。
分享