Go 语言数组
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整形、字符串或者自定义类型。
数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1,以此类推。
数组的长度不可改变。
声明数组
Go 语言数组声明需要指定元素类型及元素个数,语法格式如下:
var variable_name [SIZE] variable_type
以上为一维数组的定义方式。例如以下定义了数组 balance 长度为 10 类型为 float32:
var balance [10] float32
与Java不一样,数组不是引用类型,所以声明数组后,数据的每个元素都有了对应数据类型的零值。
初始化数组
以下演示了数组初始化:
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
初始化数组中 {} 中的元素个数不能大于 [] 中的数字。
可以使用…来代替数组的长度,Go 语言会根据元素的个数来设置数组的大小:
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
该实例与上面的实例是一样的,虽然没有设置数组的大小。
balance[4] = 50.0
以上实例读取了第五个元素。数组元素可以通过索引(位置)来读取(或者修改),索引从0开始,第一个元素索引为 0,第二个索引为 1,以此类推。
访问数组元素
数组元素可以通过索引(位置)来读取。格式为数组名后加中括号,中括号中为索引的值。例如:
var salary float32 = balance[9]
以上实例读取了数组balance第10个元素的值。
以下演示了数组完整操作(声明、赋值、访问)的实例:
packagemain
import“fmt”
func main() {varn [10]int //n 是一个长度为 10 的数组var i,j int
//为数组 n 初始化元素fori = 0; i < 10; i++ { n[i] = i + 100 }
//输出每个数组元素的值forj = 0; j < 10; j++ { fmt.Printf("Element[%d] = %d\n", j, n[j] ) }}
以上实例执行结果如下:
Element[0] = 100Element[1] = 101Element[2] = 102Element[3] = 103Element[4] = 104Element[5] = 105Element[6] = 106Element[7] = 107Element[8] = 108Element[9] = 109
Go 语言切片(Slice)
Go 语言切片是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
定义切片
你可以声明一个未指定大小的数组来定义切片:
var identifier []type
与声明数据相比,切片不需要说明长度,但未初始化的切片是nil。
或使用make()函数来创建b并初始化切片:
var slice1 []type = make([]type, len)也可以简写为slice1 := make([]type, len)
这里 len 是数组的长度并且也是切片的初始长度。
切片初始化
s :=[] int {1,2,3 }
len() 和 cap() 函数
切片是可索引的,并且可以由 len() 方法获取长度。
切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。
以下为具体实例:
packagemain
import“fmt”
func main() {varnumbers = make([]int,3,5)
printSlice(numbers)}
func printSlice(x []int){ fmt.Printf(“len=%d cap=%d slice=%v\n“,len(x),cap(x),x)}
以上实例运行输出结果为:
len=3 cap=5 slice=[0 0 0]
切片截取
可以通过设置下限及上限来设置截取切片 [lower-bound:upper-bound]
packagemain
import“fmt”
func main() { //创建切片 numbers := []int{0,1,2,3,4,5,6,7,8} printSlice(numbers)
//打印原始切片 fmt.Println(“numbers ==”, numbers)
//打印子切片从索引1(包含) 到索引4(不包含) fmt.Println(“numbers[1:4] ==”, numbers[1:4])
//默认下限为 0 fmt.Println(“numbers[:3] ==”, numbers[:3])
//默认上限为 len(s) fmt.Println(“numbers[4:] ==”, numbers[4:])
numbers1 := make([]int,0,5) printSlice(numbers1)
//打印子切片从索引 0(包含) 到索引 2(不包含) number2 := numbers[:2] printSlice(number2)
//打印子切片从索引 2(包含) 到索引 5(不包含) number3 := numbers[2:5] printSlice(number3)
}
func printSlice(x []int){ fmt.Printf(“len=%d cap=%d slice=%v\n“,len(x),cap(x),x)}
执行以上代码输出结果为:
len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8]numbers == [0 1 2 3 4 5 6 7 8]numbers[1:4] == [1 2 3]numbers[:3] == [0 1 2]numbers[4:] == [4 5 6 7 8]len=0 cap=5 slice=[]len=2 cap=9 slice=[0 1]len=3 cap=7 slice=[2 3 4]
虽然切片值在上述方面受到了其容量的限制。但是我们可以通过另外一种手段对其进行不受限制的扩展。这需要用到内建函数append。append会对切片值进行扩展并返回一个新的切片值,使用方法如下:
package mainimport "fmt"func main() { var s []string fmt.Println(s==nil) //创建并初始化容量为5的切片 mb:=make([]int,5) for i:=0;i<5;i++{ fmt.Println(mb[i]) } mb2:=append(mb,1) fmt.Println(mb2[5])}
切片的底层原理
切片在内存中的组织方式实际上是一个有 3 个域的结构体:指向相关数组的指针,切片长度以及切片容量。每个切片底层保留了一个数据的引用。
slice := []int{1, 2, 3, 4, 5}newSlice := slice[1:3]newSlice[0] = 10fmt.Println(slice)fmt.Println(newSlice)fmt.Printf("%p\n", &slice[1])fmt.Printf("%p\n", &newSlice[0])
运行结果:
10
10
这个例子证明了,新的切片和原切片共用的是一个底层数组,所以当修改的时候,底层数组的值就会被改变,所以原切片的值也改变了。当然对于基于数组的切片也一样的。
云计算时代的编程语言:Go语言课程链接:
为什么我强烈推荐你学习go语言
Go 语言环境安装
go变量与数据类型
go 条件控制及循环的基本语法
Go 语言函数
如果觉得《Go语言数组与切片》对你有帮助,请点赞、收藏,并留下你的观点哦!