数组和切片(Go语言)

数组(array)

定义

Go语言提供了数组类型的数据结构。数组是具有相同类型的一组长度固定的数据序列,这种类型可以使任意的基本数据类型或复合数据类型及自定义类型。

数组元素可以通过索引下标(位置)来读取或修改元素数据。索引从0开始,第一个元素索引为0,第二个索引为1,以此类推。数组的下标取值范围是从0开始,到长度减1。

数组一旦定义后,大小不能更改。

语法

声明数组

Go语言数组声明需要制定元素类型元素个数

  • var 变量名 [数组长度]数据类型 // 一维数组定义
  • 数组长度必须是整数且大于0
  • 为初始化的数组不是nil,也就是没有空数组(与切片不同)

初始化数组

  • var nums =[5]int{1,2,3,4,5}
    • 初始化数组中{}中的元素个数不能大于[]中的数字
  • 如果忽略[]中的数字不设置数组大小,Go语言会根据元素的个数来设置数组的大小。
    • 可以忽略声明中数组的长度并将其替换为…。编译器会自动计算长度
    • var nums = […]int{1,2,3}
    • 该实例与上面的实例是一样的,虽然没有设置数组的大小

数组长度

通过将数组作为参数传递给len()函数,可以获得数组的长度。

数组是值类型

Go语言中的数组是值类型,而不是引用类型。这意味着当它们被分配一个新变量是,将把原始数组的副本分配给新变量。如果对新变量进行了更改,则不会再原始数组中反映。

当将数组传递给函数作为参数时,将通过值传递,而原始数组将保持不变。

切片(slice)

定义

Go语言切片是对数组的抽象。

  • Go数组的长度不可改变,在特定场景中这样的集合就不太方便,Go中提供了一种灵活,功能强悍的内置类型切片(“动态数组”)
  • 与数组相比切片的长度是不固定的,可以追加元素。在追加时可能使切片的容量增大
  • 切片本身没有任何数据,只是对现有数组的引用
  • 切片与数组相比,不需要设定长度,在[]中不用设定值,相对来说比较自由
  • 从概念上slice像一个结构体,这个结构体包含了三个元素
    • 指针,指向数组中slice指定的开始位置
    • 长度,即slice的长度
    • 最大长度,也就是slice开始位置到数组的最后位置的长度

语法

声明变量

  • 声明一个未指定长度的数组来定义一个切片
    • var identifier []type
    • 切片不需要说明长度
    • 该声明方式,且未初始化的切片为空切片。该切片默认为nil,长度为o.
  • 使用make()函数创建切片
    • var slice1 []type - make([]type,len)
    • 简写为 slice := make([]type,len)
    • 可以指定容量 make([]T,length,capacity)

初始化

  1. 直接初始化

    s :=[]int{1,2,3}
    
  2. 通过数组截取来初始化切片

//声明数组
arr :=[5]int{1,2,3,4,5}

s := arr[:] //切片中包含数组所有元素

s := arr[startIndex:endIndex] // 将arr中从下标startIndex到endIndex-1下的元素创建一个新的切片(前闭后开)

s := arr[startIndex:] //缺省endIndex时表示一直到arr的最后一个元素

s := arr[:endIndex] //缺省startIndex时将表示从arr的第一个元素开始

s := arr[startIndex:endIndex:max] //显示的指定最大值 没有显示的指定时默认为数组长度

s := arr[:endIndex:max] // 缺省startIndex时表示从arr的第一个元素开始
```

3.也可以通过切片在切片上初始化切片

nums := []int{10,20,5:30}

s :=[1:]

源码

type slice struct{
	array .Pointer
	len int
	cap int
}

切片(slice)本身并非动态数据或指针数组。它内部通过指针引用底层数组,设定相关属性将数据读写操作限定在指定区域内。

切片本身只是个读对象,其工作机制类似于数组指针的一种包装。

属性cap表示切片所引用数组片段的真实长度,len用于限定可读的写元素数量。

通过在数组上截取的切片的len和cap属性计算公式如下:

len = endInex -startIndex
cap = max - startIndex

可直接创建切片对象,无需预先准备数组,因为切片是引用类型,需使用make()函数或显示初始化语句,它会自动完成底层数组内存分配。

func mian(){
	s1 := make([]int,3,5)  //指定len,cap,底层数组初始化为零值
	s2 := make([]int,3) // 省略cap,和len相等
    s3 := []int{10,20,4:30} // [10,20,0,0,30]	  
}

切片 只是很小的结构体对象,用来代替数组传参可避免复制开销。make允许在运行期动态指定数组长度,绕开了数组类型必须使用编译期常量的限制。

并非所有时候都适合用切片代替数组,应为切片底层数组可能会在堆上分配内存。而且小数组在栈上拷贝的消耗未必比make小。

len()和cap()函数

  • 切片的长度是切片中元素的数量
  • 切片的容量是从创建切片的索引开始的底层数组中元素的数量
  • 切片实可索引的,并且可以由len()方法获取长度,切片提供了计算容量的方法cap(),可以测量切片最长可以达到多少
  • cap()的结果决定了切片截取得注意细节

append()和copy()函数

  1. append()
    • 往切片中追加新元素
    • 可以往slice里面追加一个或者多个元素,也可以追加一个切片
    • append函数会改变slice引用的数组的内容,从而影响到引用同一组数组的其他slice
    • 当使用append追加元素到切片是,如果容量不够,Go就会创建一个新的内存地址来存储元素
  2. copy()
    • 复制切片元素
    • 将源切片的元素复制到目标切片中,返回复制的元素个数
    • copy方法是不会建立源切片与目标切片之间的联系,一个修改不影响另一个。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值