在上面的章节里面,我们讲过Go内置的基本数据类型。现在我们来看一下Go内置的高级数据类型,数组,切片和字典。

数组(Array)
相同数据类型固定长度有序集合

表示数组x是一个整型数组,而且数值的长度为5。

Go提供了几种不同的数组定义方法。
最基本的方式就是使用var关键字来定义,然后依次给元素赋值对于没有赋值的元素,默认为零值
varxrange函数可以用在数组,切片和字典上面range来遍历数组的时候返回数组的索引和元素值当你对一个函数返回值不感兴趣的话,可以使用下划线(_)来替代它

还有一种方式,如果知道了数组的初始值。可以像下面这样定义。

当然,即使你不知道数组元素的初始值,也可以使用这样的定义方式。

在这里我们需要特别重视数组的一个特点,就是数组是有固定长度的。
...
},
Go提供的这种可以自动计算数组长度的方法在调试程序的时候特别方便,假设我们注释掉上面数组x的最后一个元素,我们甚至不需要去修改数组的长度。
 
切片(Slice)

在上面我们说过数组是有固定长度的有序集合。这也就是说一旦数组长度定义,你将无法在数组里面多添加哪怕一个元素。数组的这种特点有的时候会成为很大的缺点,尤其是当数组的元素个数不确定的情况下。

切片
切片有一个数组所没有的特点,那就是切片的长度是可变的
容量(capacity)长度(length)

首先我们来看一下切片的定义。切片有两种定义方式,一种是先声明一个变量是切片,然后使用内置函数make去初始化这个切片。另外一种是通过取数组切片来赋值。

 

 结果

 

上面我们首先用make函数定义切片x,这个时候x的容量是5,长度也是5。然后使用make函数定义了切片y,这个时候y的容量是10,长度是5。然后我们再分别为切片x和y的元素赋值,最后输出。

两种方式只指定长度,这个时候切片的长度和容量是相同的同时指定切片长度和容量赋值的时候要注意最大的索引仍然是len(x)-1
[low_index:high_index]包括low_index的元素不包括high_index的元素

结果为

在上面的例子中,我们还省略了low_index或high_index。如果省略了low_index,那么等价于从索引0开始;如果省略了high_index,则默认high_index等于len(arr1),即切片长度。

这里为了体现切片的长度可以变化,我们看一下下面的例子:.

输出结果为

这里我们初始化arr1为容量10,长度为5的切片,然后为前面的5个元素赋值。然后输出结果。然后我们再使用Go内置方法append来为arr1追加四个元素,这个时候再看一下arr1的容量和长度以及切片元素,我们发现切片的长度确实变了。

append

输出结果为:

我们发现arr1的长度变为11,因为元素个数现在为11个。另外我们发现arr1的容量也变了,变为原来的两倍。

Go在默认的情况下,如果追加的元素超过了容量大小,Go会自动地重新为切片分配容量,容量大小为原来的两倍
使用append函数给切片增加元素copy函数用来从一个切片拷贝元素到另一个切片

输出结果

在上面的例子中,我们将slice1的元素拷贝到slice2,因为slice2的长度为5,所以最多拷贝5个元素。

[]...

 

字典(Map)
无序的键值对集合
关联数组索引键
初始化数据使用神奇的make函数

输出结果为

[]range函数,此函数一样神奇,可以用来迭代字典元素,返回key:value键值对下划线(_)

可以这样

等效于

也可以这样

 

下一个例子

试图为未经过初始化的字典添加元素会导致运行错误

当然上面的例子中,我们可以把定义和初始化合成一句。

现在我们再来看一下字典的数据访问方式。如果你访问的元素所对应的键存在于字典中,那么没有问题,如果不存在呢?

这个时候会返回零值。对于字符串零值就是””,对于整数零值就是0。但是对于下面的例子:

输出结果为

在这个例子中,很显然不存在键C,但是程序的输出结果为0,这样就和键A对应的值混淆了。

Go提供了一种方法来解决这个问题:

x["C"]

 

Go提供的内置函数delete,这个函数可以用来从字典中删除元素

输出结果为

len函数也可以用来获取字典的元素个数

最后我们再用一个稍微复杂的例子来结束字典的介绍。

我们有一个学生登记表,登记表里面有一组学号,每个学号对应一个学生,每个学生有名字和年龄。

输出结果为

当然我们也可以用初始化的方式定义字典: