Go数组、多维数组和切片(动态数组)
1.数组(一维数组)
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,数组元素通过索引(下标)来读取,修改数组元素值。
数组定义格式:
var 数组名 [size--数组长度] 数据类型
数组初始化:
先声明,再进行初始化
// var 数组名 [size] 数据类型 var arr3 [3]int // 根据索引下标进行赋值 arr3[0] = 1024 arr3[1] = 512 arr3[2] = 256
数组长度确定,在声明定义时进行初始化
var arr = [size] arr_type { ele1,ele2...,elen} // 使用 := arr := [size] arr_type { ele1,ele2...,elen}
例如,声明并且初始化 arr1 和 arr2 两个数组
var arr1 = [10]int{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} // 或者下面的格式,使用:=来进行快速初始化 arr2 := [10]int{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} // 使用 range 进行 for遍历 for _, v := range arr1 { fmt.Print(v, "\t") // 1 2 3 4 5 6 7 8 9 10 }re println() for _, v := range arr2 { fmt.Print(v,"\t") // 1 2 3 4 5 6 7 8 9 10 }
数组长度不确定,在声明定义时初始化
Go为我们提供了
...
的方式来对长度不确定的数组,进行初始化,其编译器会自行推断数组的长度。格式如下
var arr = [...] 数据类型 { 元素1,元素2,...,元素n}
例如:
var arr4 = [...]string{ "张三", "李四", "王五", } println(len(arr4)) // ... 为 3 // 注意,数组中的每个元素需要以逗号分隔, // 字符串数组中最后一个元素后也需要加分号
数组元素访问:
通过索引下标来访问数组元素:
var arrTest = [4] int {
1,7,8,3}
element1 = arrTest[0] // 1
element1 = arrTest[3] // 3
2.多维数组
多维数组定义格式:
var arrD [size][size] arr_type
注意数组的数据类型必须是统一的且唯一的。
多维数组的初始化:
多维数组的声明及初始化与一维数组是完全一样的,以二维数组举例
var arrD = [size][size] arr_type{ ele1,ele2...,elen} // 或者 arrD := [size][size] arr_type{ ele1,ele2...,elen}
在二维数组中不能使用
...
来进行数组长度不确定。多维数组的元素访问:
与一维数组是完全一样的
var arrDT = [3][3] int { { 1,3,9},{ 2,4,6},{ 5,7,8}} ele1 := arrDT [2] [0] // 5 ele2 := arrDT [1] [2] // 6 ele3 := arrDT [0] [1] // 3
3.切片(动态数组)
Go 语言切片是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
切片的定义格式
切片不需要声明长度,所以可以使用未定义数组长度来声明一个切片
var 切片名 []type
经常使用make()函数来定义声明一个切片,如下:
// make 函数的格式 var slice1 []type = make([]type, len) // 也可以简写为 slice1 := make([]type, len)
make 函数的格式:
make([]type, len ,[capacity]) // type 为切片的数据类型 // len 为切片的初始化长度 // capacity 为切片的最大容量,capacity为可选参数
若capacity 不写,则默认与len保持一致。
切片的使用
go语言提供的切片与python中的切片使用方式基本一致(切片为左闭右开,即包含左边不包含右边)
切片格式如下:
var arr = [size] arr_type { ele1,ele2,ele3...elen} // 对上面的数组进行切片 起始索引 结束索引,切片为左闭右开的格式 var slice = arr [startIndex : endIndex] // startIndex 为空,则从开始切到endIndex // endIndex 为空,则从startIndex 切到 末尾 // startIndex endIndex 都为空则从开头切到末尾
使用例子如下(tip:可以使用%v进行对切片的值显示):
// 先创建一个数组,方便一会儿切片来进行测试 var arr1 = [6]string{ "java", "python", "go", "rust", "c++", "php"} // 1. 从开头切到尾部,相当于一层拷贝,而且可以进行动态扩容 slice1 := arr1[:] println("slice1", slice1) // slice1 [6/6]0xc000057f10 // 2. 指定起始位置,默认位置不指示 slice2 := arr1[1:4] println("slice2", slice2) // slice1 [3/5]0xc000057f20 // 3. 指定终止位置,起始位置不指定 slice3 := arr1[:3] println("slice3", slice3) //slice3 [3/6]0xc000057f10 // 4. 指定区间 slice4 := arr1[1:3] println("slice4", slice4) // slice4 [2/5]0xc000057f20 // 切片遍历显示,这里只拿slice4来进行演示 for item := range slice4 { println(slice4[item]) // python go 可见切片是左开右闭的 }
len() 和 cap() 及 append ()和 copy()函数
切片是可索引的,并且可以由 len() 方法获取长度。
切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。
append() 函数可以对切片进行末尾追加,即动态扩容
copy() 函数 拷贝切片。
切片的扩容,每次是以两倍的方式进行的。
// 创建数组 var arr2 = [3]int{ 123, 456, 789} // 进行切片 sliceN := arr2[:] println(len(sliceN)) println(cap(sliceN)) // 验证其是否为动态数组,使用append追加 sliceN = append(sliceN, 333) println(len(sliceN)) // 4 println(cap(sliceN)) // 6 // 使用make函数创建切片 sliceN2 := make([]int, 3, 6) println(len(sliceN2)) // 3 println(cap(sliceN2)) // 6 // copy 拷贝切片 sliceN3 := make([]int, 3, 12) copy(sliceN3, sliceN) fmt.Printf("%v,%d,%d", sliceN3, len(sliceN3), cap(sliceN3)) // [123 456 789],3,12