首页 >后端开发 >Golang >为什么修改 Go 切片副本也会更改原始切片?

为什么修改 Go 切片副本也会更改原始切片?

Barbara Streisand
Barbara Streisand原创
2024-11-19 06:44:02269浏览

Why Does Modifying a Go Slice Copy Also Change the Original?

了解 Go 中的切片修改

在 Go 中,切片变量的行为与典型数组不同。这可能会导致意外的行为,尤其是在修改切片时。

更改原始切片的奥秘

考虑以下代码:

import "fmt"

func main() {
    A := []int{3, 4, 5, 3, 7}

    fmt.Println("Initial slice: ", A)
    funcSome(A)
    fmt.Println("Modified slice: ", A)
}

func funcSome(slice []int) {
    fmt.Println("Inside function, original slice: ", slice)
    temp := slice // copy by value

    temp[0] = 10
    fmt.Println("Inside function, modified temp: ", temp)
    fmt.Println("Inside function, original slice: ", slice)
}

当您运行此代码时,您可能会惊讶地发现修改临时切片 temp 也会修改原始切片, A.

深入研究切片内部

要理解这种行为,我们需要深入研究切片的内部结构。切片变量由三个部分组成:

  • 指针:指向保存数据的支持数组
  • 长度:切片中的元素数量
  • 容量:切片的最大容量

当您按值将切片分配给新变量时,就像我们对 temp 所做的那样:= slice,您正在创建一个浅拷贝。这意味着新切片 (temp) 与原始切片 (slice) 共享相同的支持数组和指针。

append() 困境

append( Go 中的 ) 函数通过创建新的支持数组并将现有数据复制到其中来将元素添加到切片中。但是,如果新切片的容量不足,append() 函数将通过重新分配更大的后备数组来自动增加容量。

在您的示例中,remove() 函数使用append() 创建一个新的切片片。由于 temp 和 A 共享相同的后备数组,因此对新切片的任何修改也会影响原始切片。

结论

理解 Go 中的切片修改需要熟悉其独特的内部结构。请记住,按值复制切片时,您正在创建一个浅拷贝,它共享相同的后备数组。修改切片时,此行为可能会导致意外后果。

以上是为什么修改 Go 切片副本也会更改原始切片?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn