传递slice的问题

func main() {
	nums := make([]int, 0, 10)
    
    // go 语言都是值传递
    // 例如,当我们传递一个slice时, 实际上在调用函数的函数栈帧中,会复制一个sliceHeader结构体,                 // Data 指向原slice的底层数组,go语言中如果我们传入的是内存中的一块地址,则我们可以修改这块内存上// 的值
	var appendNum = func(a []int) {
		a = append(a, 1, 2, 3)
		fmt.Println(a, len(a), cap(a))
		//fmt.Print input slice will point the data prt of sliceHeader
		fmt.Printf("a addr %p\n", a)
	}
	appendNum(nums)
	fmt.Println(nums)
	fmt.Printf("num addr %p\n", nums)
	fmt.Println(nums[:3], len(nums), cap(nums))
}
// 输出的是
// [1 2 3] 3 10
// a addr 0xc0000b20f0
// []
// num addr 0xc0000b20f0
// [1 2 3] 0 10

// 所以当我们在call appendNum之后,参数slice a的底层数组指向nums的底层数组(地址相同),当append数据之后,data指向的内存被修改,但是nums的len和cap还是原来的值,因此最后输出的是[1 2 3] 0 10

func main() {
	nums := make([]int, 0, 2)

	var appendNum = func(a []int) {
		a = append(a, 1, 2, 3)
		fmt.Println(a, len(a), cap(a))
		//fmt.Print input slice will point the data prt of sliceHeader
		fmt.Printf("a addr %p\n", a)
	}
	appendNum(nums)
	fmt.Println(nums)
	fmt.Printf("num addr %p\n", nums)
	fmt.Println(nums[:2], len(nums), cap(nums))
}

输出
[1 2 3] 3 4
a addr 0xc0000181a0
[]
num addr 0xc00000a0d0
[0 0] 0 2


对比上一段代码,这一段代码我们将nums的cap设置为2,但是我们append3个数据在a中,这会触发append的扩容机制,预估容量newsize为3, oldsize*2 = 4;newsize < oldsize *2 且old<1024 所以a会重新开辟一个新的底层数据,newsize = 2*oldsize。

上边讲述了为什么在appendNum中的cap(a) = 4, 可以发现最后输出的nums[:2] 为[0, 0], 所以a操作的底层数组已经变成另一个了。


// 注 : nums与nums[:] 等价于nums[0:len(nums)],而nums[low:high],high最大可以等于cap(nums)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值