了解Python、Perl、JavaScript的人想必都知道它们的数组是动态的,可以随需求自动增大数组长度。但Go中的数组是固定长度的,数组一经声明,就无法扩大、缩减数组的长度。但Go中也有类似的动态"数组",称为slice数据结构,在下一篇文章会详细解释它。
Go中的数组是slice和map两种数据类型的基础,这两种数据类型的底层都是通过数组实现的。
数组的存储方式
当在Go中声明一个数组之后,会在内存中开辟一段固定长度的、连续的空间存放数组中的各个元素,这些元素的数据类型完全相同,可以是内置的简单数据类型(int、string等),也可以是自定义的struct类型。
- 固定长度:这意味着数组不可增长、不可缩减。想要扩展数组,只能创建新数组,将原数组的元素复制到新数组
- 连续空间:这意味可以在缓存中保留的时间更长,搜索速度更快,是一种非常高效的数据结构,同时还意味着可以通过数值index的方式访问数组中的某个元素
- 数据类型:意味着限制了每个block中可以存放什么样的数据,以及每个block可以存放多少字节的数据
例如,使用下面的语句声明一个长度为4的int类型的数组,那么这个数组最多只能存放4个元素,且所有元素都只能是int类型。同时,还为这个数组做了初始化。
arr_name := [4]int{3,5,22,12}这个数组的结构如下图所示:

其中左上角的小格子中的数表示各元素所在数组中的位置,也就是它们对应的index,index从0开始计算。
声明、初始化和访问数组
因为Go中的数组要求数据类型固定、长度固定,所以在声明的时候需要给定长度和数据类型。
例如声明一个长度为5、数据类型为int的数组,名为arr_name。
var arr_name [5]int必须注意,虽然我们称呼数组为int类型的数组,但数组的数据类型是两部分组成的[n]TYPE,这个整体才是数组的数据类型。所以,[5]int和[6]int是两种不同的数组类型。不同数据类型,意味着如果数组赋值给另一数组时需要数据类型转换操作,而Go默认是不会进行数据类型转换的。
在Go中,当一个变量被声明之后,都会立即对其进行默认的赋0初始化。对int类型的变量会默认初始化为0,对string类型的变量会初始化为空"",对布尔类型的变量会初始化为false,对指针(引用)类型的变量会初始化为nil。
数组也是一种变量类型,也会被初始化。初始化的方式是数组中的所有元素都根据数据类型赋值0。例如int类型的数组,元素全部赋值为0,string类型的数组,元素全部赋值为""等。
所以,上面声明数组arr_name之后,它初始化后的结果如下:

可以直接输出数组:
import "fmt" var new_arr [3]int fmt.Println(new_arr) // 输出:[0 0 0]可以将数组的声明和初始化为给定值的操作合并:
arr_name := [5]int{3,5,22,12,23}如果将元素个数指定为特殊符号...,则表示通过初始化时的给定的值个数来推断数组长度:
