Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

切片作为函数参数这一章节,倒数第三段描述应该不准确 #50

Open
hookokoko opened this issue Jun 11, 2022 · 1 comment

Comments

@hookokoko
Copy link

问题描述

请在此描述你的问题,提问前请参考提问的智慧

原文是这么说的:

myAppend 函数里,虽然改变了 s,但它只是一个值传递,并不会影响外层的 s,因此第一行打印出来的结果仍然是 [1 1 1]。

这个地方我在第一次看到的时候有点歧义,虽说slice是一个值传递,但是slice中是包含是指向数组的指针的。按理说,值传递的也是数组的指针。

经过验证,不影响的准确原因应该是append触发了slice的扩容,扩容会导致copy,也就是说slice结构体中指向数组的指针发生了变化。因此外层的s不会发生变化。
如果是直接修改slice元素,内外层都会改变

func myAppend(s []int) []int {
	//s = append(s, 100)
	s[0] = 100
	fmt.Printf("s point out func: %p, %p\n", s, &s)
	return s
}

我个人的理解,如有不对,欢迎讨论~

@ricky-zhf
Copy link

ricky-zhf commented Jan 29, 2023

这里的描述也感觉有点歧义。

果真改变了原始 slice 的底层数据。这里传递的是一个 slice 的副本,在 f 函数中,s 只是 main 函数中 s 的一个拷贝。在f 函数内部,对 s 的作用并不会改变外层 main 函数的 s。
但就结果来看,对 f函数内s 的作用改变了外层 main 函数的 s。
我理解其实传的不是slice的副本,而是slice指针的副本,因为slice本身就是引用类型变量,所以在f函数中修改s的值,slice的值也被修改。

func main() {
	slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	fmt.Printf("%p\n", slice)
	f(slice)
}
func f(s []int) {
	fmt.Printf("%p\n", s)
}

输出的结果:

0x1400001c0f0
0x1400001c0f0

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants