Go语言的切片操作对底层数组的影响

本文详细解析了在Go语言中如何使用数组和切片,并展示了切片操作如何影响原始数组。通过实例说明了切片在不同情况下的扩容机制及其对原数组的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过数组或切片生成新的切片时,修改新切片可能会影响原有的数组或切片。直接上代码:

package main
import (
	"fmt"
)

func main(){

	// array是数组
	array:=[...]int{1,2,3,4,5,6,7,8,9}
	fmt.Printf("数组array的长度是%d,容量是%d\n", len(array), cap(array))

	// slice是切片,定义时其实是指向数组array的引用,容量由原数组的最后一个元素位置决定
	slice:=array[2:4]
	fmt.Printf("切片slice的长度是%d,容量是%d\n", len(slice), cap(slice))

	// slice切片追加一个元素,因为现有的容量(7)仍然能够满足追加后的空间需求(3),
	// 所以切片不会扩容,对应的引用地址就不会变化
	slice[0]=99
	slice= append(slice, 123)

	fmt.Printf("切片追加1个新元素后,原数组的值%+v\n",array)
	fmt.Printf("切片追加1个新元素后,切片的值%+v,容量是%d\n",slice, cap(slice))

	// slice切片追加一个切片(5个元素),因为现有的容量(7)将不能满足追加后的空间需求(8),
	// 所以切片会扩容(*2倍),对应的引用地址将发生变化(不再指向原数组)
	slice= append(slice,[]int{11,22,33,44,55}...)
	fmt.Printf("切片追加新元素后,切片的值%+v,容量是%d\n",slice, cap(slice))
	fmt.Printf("切片追加新元素后,原数组的值%+v\n",array)
}

结果:

数组array的长度是9,容量是9
切片slice的长度是2,容量是7
切片追加1个新元素后,原数组的值[1 2 99 4 123 6 7 8 9]
切片追加1个新元素后,切片的值[99 4 123],容量是7
切片追加新元素后,切片的值[99 4 123 11 22 33 44 55],容量是14
切片追加新元素后,原数组的值[1 2 99 4 123 6 7 8 9]

分析:

 原数组一共有7个元素,数组的len和cap均为7;

定义的切片,len为2,cap为7(重点:7是根据原数组的元素计算而来),此时切片其实是引用的原数组地址,修改切片的第1个元素值为99,其实就是修改了原数组;

向切片追加1个新元素123,追加后的切片len将是3,此时切片现有的cap为7,是能够满足追加需求的,所以切片不会扩容,对应的也就不会重新分配新地址,追加的元素将直接覆盖原数组;

继续向切片追加1个切片(5个元素),追加后的切片len将是8,将超过现有cap(7),所以此次追加将导致切片扩容,重新分配新的空间。追加行为将在新的地址空间里发生,对原数组将不产生影响,追加后的切片cap将*2倍(2*7=14);

如果将原数组改成切片,效果是一样的。定义切片的代码将是:

array:=[]int{1,2,3,4,5,6,7,8,9}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值