Skip to content
New issue

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

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

Already on GitHub? Sign in 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

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

No branches or pull requests

2 participants