数组是 Go 语言中重要的数据结构,了解它的实现能够帮助我们更好地理解这门语言,而且数组是很多复杂结构的底层数据结构,学习数组对后续理解复杂数据结构有着至关重要的作用,今天开启 golang 第一课:数组。
Go 语言提供了数组类型的数据结构,数组类型包含两个重要属性:元素的类型和数组长度。
var arr [N]T
这里声明了一个数组变量 arr,它的类型为 [N]T,其中元素的类型为 T,数组的长度为 N。
注意:数组元素的类型可以为任意的 Go 原生类型或自定义类型,而且数组的长度必须在声明数组变量时提供,Go 编译器需要在编译阶段就知道数组类型的长度,数组长度一旦确定不能更改,所以,我们只能用整型数字面值或常量表达式作为 N 值。
如果两个数组类型的元素类型 T 与数组长度 N 都是一样的,那么这两个数组类型是等价的,如果有一个属性不同,它们就是两个不同的数组类型,例如:[5]int 和 [6]int 为不同数组类型。
数组不仅是逻辑上的连续序列,而且在实际内存分配时也占据着一整块内存。 Go 编译器在为数组类型的变量实际分配内存时,会为 Go 数组分配一整块、可以容纳它所有元素的连续内存。这块内存全部空间都被用来表示数组元素,所以说这块内存的大小,就等于各个数组元素的大小之和。
如果两个数组所分配的内存大小不同,那么它们肯定是不同的数组类型。
Go 提供了预定义函数 len 可以用于获取一个数组类型变量的长度,通过 unsafe 包提供的 Sizeof 函数,我们可以获得一个数组变量的总大小,如下面代码:
var arr = [6]int{1, 2, 3, 4, 5, 6}
fmt.Println("数组长度:", len(arr)) // 6
fmt.Println("数组大小:", unsafe.Sizeof(arr)) // 48
数组大小就是所有元素的大小之和,这里数组元素的类型为 int。在 64 位平台上,int 类型的大小为 8,数组 arr 一共有 6 个元素,因此它的总大小为 6x8=48 个字节。
不进行显式初始化,那么数组中的元素值就是它类型的零值。
var arr [6]int // [0 0 0 0 0 0]
显式地对数组初始化,需要在右值中显式放置数组类型,并通过大括号的方式给各个元素赋值。
var arr = [6]int {
11, 12, 13, 14, 15, 16,
} // [11 12 13 14 15 16]
当然,我们也可以忽略掉右值初始化表达式中数组类型的长度,用“…”替代,Go 编译器会根据数组元素的个数,自动计算出数组长度:
var arr = [...]int {
21, 22, 23,
} // [21 22 23]
fmt.Printf("%T\n", arr) // [3]int
对一个长度较大的稀疏数组进行显式初始化,可以通过使用下标赋值的方式对它进行初始化,Go 编译器会根据最大的索引赋值来确定数组大小。
var arr = [...]int{
99: 1099, // 将第100个元素(下标值为99)的值赋值为1099,其余元素值均为0
}
fmt.Printf("%T\n", arr) // [100]int
通过数组变量以及下标值,可以很容易地访问到数组中的元素值,并且这种访问是十分高效的,不存在 Go 运行时带来的额外开销。
var arr = [6]int{1, 2, 3, 4, 5, 6}
fmt.Println(arr[0], arr[5]) // 1 6
fmt.Println(arr[-1]) // 错误:下标值不能为负数
fmt.Println(arr[8]) // 错误:小标值超出了 arr 的长度范围
for 循环遍历数组:
// for(i)
arr := [5]int{1,2,3,4,5}
for i := 0; i < len(arr); i++{
fmt.Println(arr[i])
}
// for range
arr := [5]int{1,2,3,4,5}
for i, v := range arr {
fmt.Printf("index=%d, value=%\n", i, v)
}
// 不需要索引 i,可以用 _进行省略
for _, v := range arr {
fmt.Printf("value=%\n", v)
}
// 不需要值 v,可以用 _进行省略
for i, _ := range arr {
fmt.Printf("index=%d\n", i)
}
阅读量:1048
点赞量:0
收藏量:0