为什么在切片上添加元素会修改另一个切片?

huangapple go评论72阅读模式
英文:

Why appending on slice modified another slice?

问题

package main

import "fmt"

func main() {
	src := []int{0, 1, 2, 3, 4, 5, 6}
	a := src[:3]
	b := src[3:]
	a = append(a, 9)

	fmt.Println(a, b)
}

输出结果:

[0 1 2 9] [9 4 5 6]

append函数是否修改了底层数组,使其变为 []int{0, 1, 2, 9, 4, 5, 6}?
切片a被复制为一个新的切片,具有新的底层数组,值为[0, 1, 2, 9],而切片b仍然指向被修改的旧数组。

谢谢任何提示,非常感谢。

英文:
package main

import "fmt"

func main() {
	src := []int{0, 1, 2, 3, 4, 5, 6}
	a := src[:3]
	b := src[3:]
	a = append(a, 9)

	fmt.Println(a, b)
}

output:

> [0 1 2 9] [9 4 5 6]

Did append modified the underlay array as []int{0, 1, 2, 9, 4, 5, 6}?
Slice a was copied as a new slice with a new underlay array with value [0, 1, 2, 9] and slice b still pointing to the old array that was modified.

Thanks for any hints, much appreciated

答案1

得分: 0

将切片a复制为一个新的切片,新的底层数组的值为[0, 1, 2, 9],而切片b仍指向被修改的旧数组。

  • a := src[:3] 创建了一个切片(指向src头部的指针,长度为3,容量为7)
  • b := src[3:] 创建了一个切片(指向src[3]的指针,长度为4,容量为4)
  • ab 共享由 src 创建的相同内存
  • a = append(a, 9),当向同一切片追加元素时,只要不超过容量,就会修改同一数组

append是否修改了底层数组为 []int{0, 1, 2, 9, 4, 5, 6}?

是的

如果append超过了acap,将会分配一个新的数组,并将数据复制到新的数组中。

请尝试以下代码:

package main

import "fmt"

func main() {
	src := []int{0, 1, 2, 3, 4, 5, 6}
	a := src[:3]
	b := src[3:]
	a = append(a, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9)

	fmt.Println(a, b)
}

输出结果:

[0 1 2 9 9 9 9 9 9 9 9 9 9] [3 4 5 6]

英文:
  • Slice a was copied as a new slice with a new underlay array with value [0, 1, 2, 9] and slice b still pointing to the old array that was modified.
    > - a := src[:3] created a slice (a pointer to the src head, length=3, capacity=7)
    > - b := src[3:] created a slice(a pointer to the src[3],length=4, capacity=4)
    > - a and b shares the same memory created by src
    > - a = append(a, 9),when appending to the same slice, as long as it does not exceed cap, it is the same array that is modified

  • Did append modified the underlay array as []int{0, 1, 2, 9, 4, 5, 6}
    > YES

If the append exceed the cap of a, new array will be allocated and data will be copied the the new array

try this out:

package main

import "fmt"

func main() {
	src := []int{0, 1, 2, 3, 4, 5, 6}
	a := src[:3]
	b := src[3:]
	a = append(a, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9)

	fmt.Println(a, b)
}

Output:
> [0 1 2 9 9 9 9 9 9 9 9 9 9] [3 4 5 6]

huangapple
  • 本文由 发表于 2022年2月11日 09:24:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/71074298.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定