数组(Array)
Last updated
Was this helpful?
Last updated
Was this helpful?
本节我们介绍Golang中的数组(Array),下一节再介绍切片(Slice)。 数组是隶属同一种数据类型的元素的有序集合。例如集合5, 8, 9, 79, 76就可以用数组来表示。在Golang中,一个数组不允许存储不同数据类型的元素。
Golang中数组的数据类型格式为[n]T
。其中n
表示数组元素个数,T
表示元素类型,数组声明之后其长度不能再改变。注意这里的n
也是属于数组类型的一部分,[3]int
和[4]int
数据类型是不相同的。
有多种不同的方式可以声明数组,我们一个一个看。
这里var a [3]int
声明了一个元素个数为3,元素类型为int
的数组。这种方式声明的数组,其元素会自动初始化为对应元素类型的零值。这里数组a
的元素类型为int
,因此其元素自动初始化为0
(int
类型对应的零值为0
)。该程序输入如下:[0 0 0]
。
数组的索引值从0
到length - 1
。现在我们来给数组赋一些值。
Golang提供的变量简写声明方式(参考前面变量部分)同样适用于数组,格式如下:
这里我们使用简写方式时将数组的所有元素一个不漏的进行了手动初始化,如果我们无法给出所有元素的手动初始化,也不必全部给出,但简写形式要求至少需要给出一个元素的初始化值。
语句a := [3]int{12}
声明了长度为3的数组,但是我们并未全部给出初始值,仅给出了第一个元素的初始值12
。剩下的另外两个元素会自动初始化为0
。执行结果如下:[12 0 0]
。
声明数组时还可以将n
换为...
,这样Golang编译器会替你确认数组的长度,看个例子:
注意,数组的长度n
也是数组数据类型的一部分。 因此[5]int
和[25]int
是不同的数据类型。当然这也能印证另外一点,数组声明之后其长度是不能再改变的。我们前面一段程序中声明了数组变量b
,数据类型为[3]int
,跟数组a
的变量类型是一样的,因此类型兼容,才可以赋值,如果我们改成下面的程序,将数组b
声明为var b [4]int
就会报错:
从这点可以看出来,Golang的数组不是很灵活,因此提供了另外一种更加高级的数据类型切片(Slice),下一节我们再介绍。
值传递是说变量赋值时直接传递变量的值,而不是变量的引用(或地址);而引用传递则是传递变量的引用,并不会传递变量本身的值。听起来比较抽象,其实非常简单,试想一下,假如某个数组变量存储了非常非常多的元素,每次传递该变量都将所有的元素考过来考过去效率肯定非常低,但是直接传递该数组变量的引用(或地址)效率就非常高。这里我们仅讨论下值传递和引用传递的不同,这二者并没有绝对的好坏,只不过不同的传递方式适用于不同的场景罢了,比如函数式编程就推崇函数调用时按值传递,函数应该是纯函数,每次以相同的参数去调用一个纯函数应该是幂等的。
Golang中数组是一种值类型的数据类型,意思是说如果我们将数组变量a
赋值给数组变量b
,那么数组a
的所有元素会拷贝给数组b
,这时如果我们对数组b
做了修改,不会对原数组a
有任何影响。看一下下面的程序:
如果我们把一个数组作为参数传递给一个函数,原理一样,在函数内如果对参数做了任何修改,也不会影响原数组。
Golang中通过len
函数来获取数组的长度。
range
遍历数组我们可以使用for
循环来遍历数组。
Golang针对数组提供了一种更加简洁的遍历方式,结合for
语句和range
。
如果你用不着索引值,可以使用占位标识符_
:
当然,你可以通过该方式忽略元素值。
目前为止,我们创建的数组都是一维数组。Golang当然也可以创建多维数组:
这就是我们要介绍的数组的全部内容。由于数组的长度是固定不可变的,因此不够灵活。下一节介绍的切片就是为了解决这个问题的,实际上Golang中切片比数组更常用。
a[0] = 12
即给数组a
的第一个元素赋值,该程序输出如下:[12 78 50]
。
执行结果如下:[12 78 50]
。
这里我们声明数组变量a
时使用的是[...]T
,但是a
的数组类型仍然是[3]int
。执行结果如下:
执行结果如下:
学过C语言的应该都听过值传递和引用传递,不了解的话可以参考。这里说的变量传递其实就是将一个变量赋值给另外一个变量。
该程序中我们将数组a
赋值给数组b
,Golang会把数组a
的所有元素拷贝一份给数组b
,然后我们将数组b
的第一个元素赋值为Singapore
,并不影响数组a
。执行结果如下:
该程序中函数内部将参数num
的第一个元素改为55
,但是并不影响远数组,执行结果如下:
输出如下:
该程序使用for
语句按数组的索引从0开始访问数组。输出如下:
这里的for i, v := range a
语句会返回数组元素的索引和值i
, v
。执行结果如下:
这里我们首先通过变量声明的简写方式声明了一个二维数组a
。这里需要注意,a
数组初始值列表中最后的逗号不允许省略,否则Golang会自动在行尾插入分号导致语法错误,具体见这里:。另外一个二维数组b
声明后手动挨个进行了赋值。printarray
函数使用了两个for range
循环来打印数组值。该程序执行结果如下: