首页 > 解决方案 > 为什么在 Go 中追加 slice 会改变原始 slice?

问题描述

我有这个代码:

// The input param is A := []int{3, 4, 5, 3, 7}
func someFunc(A []int) int {   
...
    ways := 0       
    i := 0
    for i < len(A) {
        if i+1 == len(A) || i == len(A) {
            fmt.Println("break")
            break
        }
        tempA := A // copy the slice by value

        fmt.Println("A: ", A)
        fmt.Println("tempA: ", A)
        fmt.Println()

        newArr = remove(tempA, i)

        if isAesthetic(newArr) {
            ways++
        }
        i++
    }
...
}

func remove(slice []int, s int) []int {
    return append(slice[:s], slice[s+1:]...)
}

输出:

A:  [3 4 5 3 7]
tempA:  [3 4 5 3 7]

A:  [4 5 3 7 7]
tempA:  [4 5 3 7 7]

A:  [4 3 7 7 7]
tempA:  [4 3 7 7 7]

A:  [4 3 7 7 7]
tempA:  [4 3 7 7 7]

该变量A也会发生变化,而我只是按值将其复制到tempA. 还有就是append()函数,为什么之前 append 的 slicetempA也变了?

标签: goappendslice

解决方案


类型的切片变量[]T,也称为切片头,描述了后备数组的连续部分。它与数组数据分开存储。

您可以将其想象为一个结构,其中包含长度和指向数组某项(不一定是第一项)的指针。

当您分配切片变量的值时,您实际上是在分配切片头所持有的长度和指针。所以tempA最终引用与A. 然后索引任一将访问相同的底层数组项。

推荐阅读:https ://blog.golang.org/slices


推荐阅读