Go语言中的切片类型(slice)

切片和数组

数组长度固定,切片可以添加元素,都是保存多个相同类型的元素,切片的底层由数组实现。

切片的创建

// 方法一
var hello []int  // 声明切片
hello = make([]int,10)  // 创建一个长度为10的切片,本质上应该是分配内存空间

// 方法二
hello := make([]int,10)  // 也可以直接一步完成

// 方法三
hello := []int{1,2,3}  // 不使用make,直接创造一个有初始值的切片
	

数组的创建

// 数组的创建
var hello [10]int
// or
hello := [10]int{1,2,3}  // 后面7个元素的值是0
// or
hello := [...]int{1,2,3}  // 数组长度为3 

切片的长度

切片和数组的长度都使用len()函数

hello := make([]int,10) // 声明并创建一个切片
fmt.Println(len(hello)) // 打印切片长度,输出10

遍历切片

切片和数组相同都可以直接使用for循环通过下表访问,或者使用for …range遍历

for index,val := range hello{
	fmt.Println(index,val)  // index是下标,val是值
}

拼接两个切片

a := []int{1,2,3}
b := []int{4,5,6}
a = append(a,b...)
fmt.Println(a)  // [1 2 3 4 5 6]

截取部分切片/数组元素

var hi = [5]int{1,2,3,4,5}
hello := hi[1:3]  // hi[1]和hi[2]赋值给hello.如果hello := hi,那么hello是数组
// hi[:k]和hi[0:k]效果相同,从下标0到下标k-1
// hi[k:]和hi[k:len(hi)]相同,下标k到结尾

此处切片底层的数组和的地址在hi数组的地址范围之内。
hi和hello会同步修改,切片append添加元素也会修改对应地址的hi数组,如果切片hello的尾地址超出hi数组的尾地址,那么这就脱钩了,切片的底层就会创建一个新的数组了,开辟一片新的内存空间,然后把原来的数据拷贝过去

添加元素

s = append(s,element) 

删除元素

a = a[0:len(a)-1]  // 删除最后一个元素
a = a[1:len(a)]  // 删除第一个元素

通过指针访问数组/切片

go语言允许对数组进行值传递,但对于需要修改数组内容的场景可以使用指针传递。当然也可以通过值传递来实现,把修改完的数组重新赋值给原来的数组就可以了,但是显然使用指针操作更加高效,节省内存空间。
指针的获取与访问,如下

a := []int{0,1,2,3}
p := &a
fmt.Println((*p)[1])

无法对指针使用len函数获取长度,也无法对指针变量直接使用下标索引。这和C语言类似。

二维切片和切片的底层

切片的底层是用数组实现的,二维切片则是通过添加一维切片实现。

每一个元素都是一个一维度的切片。可以把二维切片视作是每个元素都是一个切片的一维切片。(应该是通过指针实现,没看源代码)

var a [][]int  // a := make([][]int,0)也可以正常运行
k := make([]int,4)
a = append(a,k)
a = append(a,k)
fmt.Println(a)  // [[0 0 0 0] [0 0 0 0]]
a[0][1] = 1
fmt.Println(a)  // [[0 1 0 0] [0 1 0 0]]
k[1] = 2
fmt.Println(a)  // [[0 2 0 0] [0 2 0 0]]

结果很神奇,整列的值都被修改了。回到前面说的,切片的底层是数组,而这个二维切片都是通过k来实现的,a[0]和a[1]指向的都是k,只要k被修改了,a[0]和a[1]对应的元素也就修改了。(下面这句概括了这一段)
在上面这个示例中,a[0] a[1] k指向的都是同一片物理内存空间

通过数组来创建的切片,两者会同步修改,不论修改数组还是切片,都会修改对应的内存空间。

但是,当切片不断append元素,切片的长度超出了底层数组以后,该切片对应的就是新的数组了。

最重要的一句,加粗。

切片的底层数组并不能增长大小。如果数组没有足够的空间来保存新的元素,所有的元素会被拷贝至一个新的更大的数组,并且切片会被更新为引用这个新的数组。
–《Head First GO语言程序设计》

参考资料:《Head First GO语言程序设计》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值