请教 golang slice 相关的问题

2019-07-09 11:29:51 +08:00
 wewin

我们知道 golang 中 slice 是引用类型,我声明长度为 10 的 slice,往其中插入了 6 个元素。打印能看到 addres4、addres5 地址相同,但是在 main 中打印 slice 的值和在 someChage 方法中打印的结果竟然不一样,请问大佬,这是什么原因?

代码:

package main

import "fmt"

func someChage(slice []int) {
	fmt.Printf("addres2: %p\n", slice)

	slice = append(slice, 1, 2, 3)
	fmt.Printf("addres3: %p\n", slice)

	slice = append(slice, 4, 5, 6)
	fmt.Printf("addres4: %p\n", slice)
	fmt.Println(slice)
}

func main() {
	slice := make([]int, 0, 20)
	fmt.Printf("addres1: %p\n", slice)
	someChage(slice)

	fmt.Printf("addres5: %p\n", slice)
	fmt.Println(slice)
}

结果:

addres1: 0xc00007a000
addres2: 0xc00007a000
addres3: 0xc00007a000
addres4: 0xc00007a000
[1 2 3 4 5 6]
addres5: 0xc00007a000
[]
4048 次点击
所在节点    Go 编程语言
25 条回复
reage
2019-07-09 14:19:34 +08:00
slice := make([]int, 0, 20)
你将 20 改为 2 看下,就看到变化。了解下 map 的 cap 参数
rrfeng
2019-07-09 14:41:35 +08:00
刚好前几天看到一篇文章,可以解惑。
《 Go Slices are Fat Pointers 》
https://nullprogram.com/blog/2019/06/30/
shawn7
2019-07-09 14:49:34 +08:00
明白了,2 楼发的文章讲的很清楚。谢谢楼主
liulaomo
2019-07-09 20:34:34 +08:00
jimmzhou
2019-07-09 22:43:28 +08:00
当把 slice 作为参数,本身传递的是值,但其内容就 byte* array,实际传递的是引用,所以可以在函数内部修改,但如果对 slice 本身做 append,而且导致 slice 进行了扩容,实际扩容的是函数内复制的一份切片,对于函数外面的切片没有变化。
package main

import(
"fmt"
)

func someChage(slice *[]int) {
fmt.Printf("addres2: %p\n", slice)

*slice = append(*slice, 1, 2, 3)
fmt.Printf("addres3: %p\n", slice)

*slice = append(*slice, 4, 5, 6)
fmt.Printf("addres4: %p\n", slice)
fmt.Println(slice)
}

func main() {
slice := make([]int, 0, 20)
fmt.Printf("addres1: %p\n", slice)
someChage(&slice)

fmt.Printf("addres5: %p\n", slice)
fmt.Println(*slice)
}

输出:
addres1: 0xc00009c000
addres2: 0xc00005e420
addres3: 0xc00005e420
addres4: 0xc00005e420
[1 2 3 4 5 6]
addres5: 0xc00009c000
[1 2 3 4 5 6]

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/581264

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX