Go语言-->数组
Go语言–>数组
1. Go语言数组的定义
Go语言的数组在声明时必须指定元素的类型和数组的大小。数组大小是数组类型的一部分,也就是说,Go中的数组是具有固定大小的,不支持动态调整大小。
语法:
var arr [n]T
n
:表示数组的长度(即元素的个数)。T
:表示数组中元素的类型。
示例:
var arr [5]int // 定义一个长度为5的整数数组
2. Go语言数组的初始化
数组在声明时可以通过初始化语法来为数组元素赋初值。如果没有显式初始化,数组的元素会被自动初始化为其类型的零值。例如,int
类型的数组元素初始化为0
,bool
类型初始化为false
,string
类型初始化为空字符串。
1. 直接初始化数组
这是最常见的方式之一,直接为数组指定固定大小和元素值。
示例:
var arr1 [3]int // 默认初始化为 [0, 0, 0]
var arr2 = [3]int{1, 2, 3} // 显式初始化为 [1, 2, 3]
这行代码声明了一个大小为5的float32
类型数组,并给定了初始化的值。该数组的类型为[5]float32
,大小是5。
2. 通过字面量在声明数组时快速初始化数组
这种方式更简洁,在声明和初始化数组的同时进行。
示例:
balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
这里的balance
是一个[5]float32
类型的数组,它的长度是5,并通过字面量直接初始化。这种方式省略了var
关键字,使用:=
进行类型推断。
3. 数组长度由元素个数推断
Go语言的编译器可以通过元素个数自动推断数组的长度。只需要在数组声明中使用...
代替长度即可。
示例:
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
在这个例子中,balance
数组的长度是由元素的数量推断出来的,长度为5。
也可以通过:=
方式进行初始化:
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
这种方式的数组类型也是[5]float32
,编译器自动根据数组的元素个数推断出数组长度为5。
4. 通过指定下标进行部分初始化
Go允许你在初始化数组时指定某些下标的值,其他未指定的元素会自动初始化为零值。
示例:
balanced := [5]float32{1: 2.0, 3: 7.0}
在这个例子中,balanced
数组的大小是5。数组元素balanced[1]
被初始化为2.0
,balanced[3]
被初始化为7.0
,其他元素(balanced[0]
、balanced[2]
、balanced[4]
)会自动初始化为0
(float32
的零值)。
5. 总结和比较
- 固定长度初始化:可以显式指定数组长度并给出初值,或者使用
...
让编译器推断数组长度。 - 部分初始化:允许通过下标指定特定元素的值,其他元素将使用类型的零值进行初始化。
示例代码
package mainimport "fmt"func main() {// 直接初始化数组var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}fmt.Println(balance)// 快速初始化balance2 := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}fmt.Println(balance2)// 编译器推断数组长度balance3 := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}fmt.Println(balance3)// 部分初始化balanced := [5]float32{1: 2.0, 3: 7.0}fmt.Println(balanced) // 输出: [0 2 0 7 0]
}
3. Go语言数组的长度
Go语言中的数组是固定大小的。数组的大小是类型的一部分,也就是说,数组的类型不仅包括元素的类型,还包括数组的长度。因此,两个长度不同的数组被视为不同的类型。
示例:
var arr1 [3]int
var arr2 [5]int
// arr1 和 arr2 是不同的类型
4. Go语言数组的遍历
Go语言提供了多种遍历数组的方法。最常用的是通过for
循环或range
关键字来遍历数组。
使用 for
循环遍历:
arr := [3]int{1, 2, 3}
for i := 0; i < len(arr); i++ {fmt.Println(arr[i]) // 输出: 1 2 3
}
使用 range
遍历:
range
会返回每个元素的索引和元素值,可以通过 range
获取索引和值。
arr := [3]int{1, 2, 3}
for i, v := range arr {fmt.Println(i, v) // 输出: 0 1, 1 2, 2 3
}
如果只关心值,可以省略索引:
for _, v := range arr {fmt.Println(v) // 输出: 1 2 3
}
5. Go语言数组的传递
Go语言中的数组是值类型,这意味着当数组作为参数传递给函数时,数组会被复制。这样传递可能会导致内存消耗较大,尤其是当数组较大时。
传递数组:
func modifyArray(arr [3]int) {arr[0] = 100fmt.Println(arr) // 输出: [100 2 3]
}func main() {arr := [3]int{1, 2, 3}modifyArray(arr)fmt.Println(arr) // 输出: [1 2 3],原数组未受影响
}
使用切片代替数组传递(推荐做法):
切片(Slice)是Go语言中动态数组的替代方案,它是对数组的一种引用,不会复制整个数组。
func modifySlice(slice []int) {slice[0] = 100fmt.Println(slice) // 输出: [100 2 3]
}func main() {arr := [3]int{1, 2, 3}slice := arr[:]modifySlice(slice)fmt.Println(arr) // 输出: [100 2 3],原数组被修改
}
6. Go语言数组的零值
Go中的数组会被自动初始化为零值。例如,对于整型数组,所有元素会被初始化为0
;对于布尔型数组,所有元素会被初始化为false
;对于字符串型数组,所有元素会被初始化为空字符串。
示例:
var arr [3]int
fmt.Println(arr) // 输出: [0 0 0]
7. Go语言多维数组
Go语言支持多维数组,也就是说,你可以创建数组的数组。例如,二维数组或三维数组。每一维都必须明确指定大小。
示例:
var arr [2][3]int // 二维数组,包含2行3列
arr[0][0] = 1
arr[1][2] = 5
fmt.Println(arr) // 输出: [[1 0 0] [0 0 5]]
8. Go语言的切片(Slice)与数组的关系
在Go中,切片(Slice)是更常用的数据结构,它可以动态增长,通常用于数组的处理。切片实际上是对数组的一个视图,它包含了数组的一部分或者整个数组。
与数组不同,切片的大小和容量是可以变化的,且切片操作不会复制数据,它只是引用了数组的一部分。
示例:
arr := [5]int{1, 2, 3, 4, 5}
slice := arr[1:4] // 创建一个切片,包含数组的第二到第四个元素
fmt.Println(slice) // 输出: [2 3 4]
切片的灵活性使得它成为Go语言中常用的数据结构,而数组一般在处理需要固定长度的情况时使用。
总结
- Go中的数组是固定大小的、值类型的,必须在声明时指定大小。
- 数组的长度是类型的一部分,长度不同的数组视为不同类型。
- 数组传递是值传递,通常建议通过切片来操作数组,以避免不必要的数组复制。
- 数组初始化可以通过默认值或显式赋值来完成,未初始化的元素会被赋予类型的零值。
- 切片是数组的引用类型,更灵活,支持动态增长,并且是Go中更常用的数据结构。