go slice append 分析
先看一段代码:
func main() {
s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
p1 := s[:3]
p2 := s[4:]
p3 := append(p1, p2...)
fmt.Printf("p1 = %v \n", p1)
fmt.Printf("p2 = %v \n", p2)
fmt.Printf("p3 = %v \n", p3)
}
运行结果:
p1 = [1 2 3]
p2 = [6 7 8 9 9]
p3 = [1 2 3 5 6 7 8 9]
结果是对的。但是p2的值就说明一些问题
期望值应该是:
p2 = [5 6 7 8 9]
下面看一下实际运行的流程:
func main() {
s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
p1 := s[:3]
p2 := s[4:]
fmt.Printf("s = %p s = %v \n", s, s)
fmt.Printf("p1 = %p v1 = %v len = %v \n", p1, p1, len(p1))
fmt.Printf("p2 = %p v2 = %v len = %v \n", p2, p2, len(p2))
p3 := append(p1, p2...)
fmt.Printf("s = %p s = %v \n", s, s)
fmt.Printf("p1 = %p v1 = %v \n", p1, p1)
fmt.Printf("p2 = %p v2 = %v \n", p2, p2)
fmt.Printf("p3 = %p v3 = %v \n", p3, p3)
}
运行结果:
PS D:\test\test> go run main.go
s = 0xc00000c320 s = [1 2 3 4 5 6 7 8 9]
p1 = 0xc00000c320 v1 = [1 2 3] len = 3
p2 = 0xc00000c340 v2 = [5 6 7 8 9] len = 5
s = 0xc00000c320 s = [1 2 3 5 6 7 8 9 9]
p1 = 0xc00000c320 v1 = [1 2 3]
p2 = 0xc00000c340 v2 = [6 7 8 9 9]
p3 = 0xc00000c320 v3 = [1 2 3 5 6 7 8 9]
解释:
*p3 == *s
append操作的是0xc00000c320指针,也就是s变量,
所以,在执行完append后,s的值已经改变,p1,p2的结果是截取切片s的,所以p1,p2
也会跟着变化。
*p1 != *p2
说明截取切片存储的值应该是
p1 = *s[:3]
p2 = *s[4:]