Go语言数组的定义和使用(非常详细)
数组是Go语言复合数据类型的基础,了解Go语言的数据结构,一般从数组开始学习。理解了数组的工作原理,学习切片、映射及列表才会更加容易。
数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1,以此类推。
数组元素的索引如图1所示。
图1:数组元素的索引
数组元素的类型可以是任意的原始类型,如 int、string 或者自定义类型。数组长度必须是一个非负整数的常量(或常量表达式),数组长度也是数组类型的一部分,所以,[20]int 和 [100]int 不是同一种类型。
Go语言数组的声明需要指定元素的类型及元素的个数,语法格式如下:
举几个例子:
数组的特点可以总结为以下几点:
数组的初始化有以下几种情况:
1) 使用数组字面量可以快速创建并初始化数组,数组字面量可以声明数组中元素的数量,并指定每个元素的值,例如:
2) 当数组的长度不确定时,可以使用
3) 当知道数组的总长度时,还可以给特定的下标指定具体的值。通过索引值进行初始化,没有初始化元素时使用类型默认值,例如:
4) 当不确定数组的总长度时,同样也可以给特定的下标指定具体的值。通过索引值进行初始化,数组长度由最后一个索引值确定,没有指定索引的元素被初始化为类型的零值,例如:
请看下面的Go语言代码:
图2:访问数组元素
数组的值也可以是指针。例如,声明一个所有元素都是指针的数组,然后使用
请看下面的Go语言示例:
数组作为变量类型,包括数组长度和每个元素的类型两个部分。只有这两部分都相同的数组才是类型相同的数组,才能相互赋值,例如:
Go语言中允许使用多维数组,因为数组属于值类型,所以,多维数组的所有维度都会在创建时自动初始化零值,多维数组尤其适合管理具有父子关系或者与坐标系相关联的数据。
声明多维数组的语法格式如下:
二维数组是最简单的多维数组,二维数组本质上是由多个一维数组组成的。
例如,声明一个二维数组:
请看下面的Go语言代码:
数组的声明
Go语言数组是具有相同类型的一组已经编号且长度固定的数据项序列,这个序列可以是有序的也可以是无序的,组成数组的各个变量称为数组的元素。数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1,以此类推。
数组元素的索引如图1所示。
图1:数组元素的索引
数组元素的类型可以是任意的原始类型,如 int、string 或者自定义类型。数组长度必须是一个非负整数的常量(或常量表达式),数组长度也是数组类型的一部分,所以,[20]int 和 [100]int 不是同一种类型。
Go语言数组的声明需要指定元素的类型及元素的个数,语法格式如下:
var 数组变量名 [元素数量]Type
对格式的说明:- 数组变量名:数组声明及使用时的变量名。
- 元素数量:数组的元素数量,可以是一个表达式,但最终通过编译器计算的结果必须是整型数值,元素数量不能含有到运行时才能确认大小的数值。
- Type:可以是任意基本类型,包括数组本身,类型为数组本身时,可以实现多维数组。
举几个例子:
//声明一个包含5个元素的整型数组 var array [5]int //声明一个包含3个元素的字符串数组 var team [3]string数组一旦声明,它存储的数据类型和数组长度就都不能修改了。所以,如果需要存储更多的元素,必须先创建一个更长的数组,然后把原来数组中的值复制到新数组中。
数组的特点可以总结为以下几点:
- 数组创建完后长度就固定了,不可以再添加元素。
- 数组是值类型,数组赋值或作为函数参数都是值复制。
- 数组长度是数组类型的组成部分,例如,[10]int 和 [20]int 表示不同的类型。
- 可以根据数组创建切片。
数组的初始化
Go语言在声明变量时,都是使用相应类型的零值来初始化变量的,数组也一样。数组初始化时,其每个元素都被初始化为对应类型的零值。例如,上面的整型数组中,每个元素都被初始化为 0(整型的零值)。数组的初始化有以下几种情况:
1) 使用数组字面量可以快速创建并初始化数组,数组字面量可以声明数组中元素的数量,并指定每个元素的值,例如:
//声明一个包含3个元素的整型数组 //用具体值初始化每个元素 a := [3]int {1,2,3}
2) 当数组的长度不确定时,可以使用
…
来代替数组的长度,Go语言会根据初始化时数组元素的数量来确定该数组的长度,例如:
//声明一个整型数组 //用具体值初始化每个元素 //长度由初始化的值来确定 a := […]int {1,2,3}
3) 当知道数组的总长度时,还可以给特定的下标指定具体的值。通过索引值进行初始化,没有初始化元素时使用类型默认值,例如:
//声明一个包含3个元素的整型数组 //用具体值初始化索引为1和2的元素 //其余元素保持类型默认值 a := [3]int {1:1,2:3}
4) 当不确定数组的总长度时,同样也可以给特定的下标指定具体的值。通过索引值进行初始化,数组长度由最后一个索引值确定,没有指定索引的元素被初始化为类型的零值,例如:
//声明一个整型数组 //用具体值初始化索引为1和2的元素 //长度由最后一个索引值来确定 //其余元素保持零值 a := […]int {1:1,2:3}
数组的使用
与其他编程语言一样,Go语言的数组可以通过数组下标(索引位置)来访问或修改数组的元素。1) 访问数组元素
数组的每个元素都可以通过索引下标来访问,索引下标的范围是从 0 开始,第一个元素索引为 0,第二个元素索引为 1,以此类推。元素的数目(长度或者数组大小)必须是固定的并且在声明数组时就指定的,数组长度最大为 2GB。请看下面的Go语言代码:
package main import "fmt" func main() { var n [10]int /*n 是一个长度为 10 的数组*/ var i,j int /*为数组 n 初始化元素*/ for i = 0; i < 10; i++ { n[i] = i + 100 /*设置元素为 i + 100*/ } /*输出每个数组元素的值*/ for j = 0; j < 10; j++ { fmt.Printf("元素[%d] = %d\n", j, n[j] ) } }运行结果如图2所示。
图2:访问数组元素
2) 修改数组元素
数组是效率很高的数据结构,因为数组在内存分配中是连续的,要访问数组中的某个单独元素,需要使用[]
运算符,例如:
//声明一个包含5个元素的整型数组 //用具体值初始化每个元素 a := [5]int {1,2,3,4,5} //修改索引为2的元素的值 a[2] = 8
数组的值也可以是指针。例如,声明一个所有元素都是指针的数组,然后使用
*
运算符访问元素指针所指向的值。请看下面的Go语言示例:
//声明一个包含5个元素的整型数组 //用整型指针初始化索引为0和1的数组元素 a := [5]*int {0: new(int), 1: new(int)} //为索引为0和1的元素赋值 *a[0] = 1 *a[1] = 2在Go语言中,数组是一个类型值,也就是说,数组可以像函数一样用在赋值操作中,变量名代表整个数组,因此,同样类型的数组可以赋值给另一个数组,例如:
//声明一个包含5个元素的字符串数组 var a1 [5]string //声明第二个包含5个元素的字符串数组 //用颜色初始化数组 a2 := [5]string{ " red ", "blue ", "green ", "yellow ", "pink "} //把a2的值赋值给a1 a1 = a2赋值之后,两个数组的值完全一样。
数组作为变量类型,包括数组长度和每个元素的类型两个部分。只有这两部分都相同的数组才是类型相同的数组,才能相互赋值,例如:
//声明一个包含4个元素的字符串数组 var a1 [4]string //声明第二个包含5个元素的字符串数组 //用颜色初始化数组 a2 := [5]string{ " red ", "blue ", "green ", "yellow ", "pink "} //将a2赋值给a1 a1 = a2此时会出现错误:
cannot use a2 (type [5]string) as type [4]string in assignment
与之前的参数传递一样,如果赋值数组指针,只会赋值指针的值,而不会赋值指针所指向的值,例如://声明第一个包含3个元素的指向字符串的指针数组 var a1 [3]*string //声明第二个包含3个元素的指向字符串的指针数组 //使用字符串指针初始化数组 a2 := [3]*string { new(string), new(string), new(string)} //使用颜色为每个元素赋值 *a2[0] = "red" *a2[1] = "blue" *a2[2] = "green" //将a2赋值给a1 a1 = a2赋值操作之后,两个数组指向同一组字符串。
多维数组
数组本身只有一个维度,但是可以组合多个数组来创建多维数组。Go语言中允许使用多维数组,因为数组属于值类型,所以,多维数组的所有维度都会在创建时自动初始化零值,多维数组尤其适合管理具有父子关系或者与坐标系相关联的数据。
声明多维数组的语法格式如下:
var array_name [size1][size2]…[sizen] array_type
其中,array_name 为数组的名字,array_type 为数组的类型,size1、size2…sizen 为数组每一维度的长度。二维数组是最简单的多维数组,二维数组本质上是由多个一维数组组成的。
例如,声明一个二维数组:
//声明一个二维整型数组,两个维度的长度分别是 4 和 2 var array [4][2]int //使用数组字面量来声明并初始化一个二维整型数组 array = [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}} //声明并初始化数组中索引为 1 和 3 的元素 array = [4][2]int{1: {20, 21}, 3: {40, 41}} //声明并初始化数组中指定的元素 array = [4][2]int{1: {0: 20}, 3: {1: 41}}此时为了访问单个元素,需要组合使用
[]
运算符,例如:
//声明一个 2×2 的二维整型数组 var array [2][2]int //设置每个元素的整型值 array[0][0] = 10 array[0][1] = 20 array[1][0] = 30 array[1][1] = 40与一维数组相同,只要类型一致,就可以将多维数组互相赋值。多维数组的类型包括两个部分,即每一维度的长度和存储在元素中数据的类型。
请看下面的Go语言代码:
//声明两个二维整型数组 var array1 [2][2]int var array2 [2][2]int //为array2的每个元素赋值 array2[0][0] = 10 array2[0][1] = 20 array2[1][0] = 30 array2[1][1] = 40 //将 array2 的值赋值给array1 array1 = array2实际上,数组中的每个元素都是一个单独的值,所以,可以独立复制某个维度,例如:
//将 array1 的索引为 1 的维度复制到一个同类型的新数组中 var array3 [2]int = array1[1] //将数组中指定的整型值复制到新的整型变量中 var value int = array1[1][0]