失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Go语言数组与切片

Go语言数组与切片

时间:2024-02-18 01:41:43

相关推荐

Go语言数组与切片

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语言数组与切片》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。