首页  >  文章  >  后端开发  >  Go 中追加的奇怪行为

Go 中追加的奇怪行为

王林
王林转载
2024-02-02 14:13:261017浏览

Go 中追加的奇怪行为

问题内容

我正在尝试使用 Go 解决 LeetCode 上的子集问题。我想出了以下解决方案:

func subsets(nums []int) [][]int {
    sol := make([][]int,0)
    temp:= make([]int,0)

    var backtrack func(idx int)
    backtrack = func(idx int) {
        sol = append(sol, temp)
        fmt.Println(temp, append([]int{},temp...))

        if idx == len(nums) {
            return
        }

        for i:= idx; i<len(nums);i++{
            temp = append(temp,nums[i])
            backtrack(i+1)
            temp = temp[:len(temp)-1]
        }

    }
    backtrack(0)
    return sol

}

但是,这个解决方案是不正确的。我注意到我需要使用append(sol,append([]int{},temp...))而不是仅仅sol=append(sol,temp)。

即使 fmt.Println(temp,append([]int{}, temp...)) 语句为 temp 和append([]int{}, temp...) 生成相同的输出,使用append([]int{}, temp...) 的更正版本实际上有效。有人可以解释在这种情况下 temp 和 append([]int{}, temp...) 之间的区别吗?为什么修正后的版本可以工作,而初始版本却不能?

预计 tempappend([]int{},temp...) 相同tempappend([]int{},temp...) 相同


正确答案


sol =append(sol, temp) 的问题是您将切片 temp 添加到 sol

正确答案

sol =append(sol, temp) 的问题是您将切片 temp 添加到 sol 中,而不是切片“内部”的项目。正如

Slice 内部博客文章temp 在每次迭代中重用,因此 temp 切片下的数组内容将被覆盖,并且您之前添加到 sol 的切片内的值也将被覆盖已修改(因为切片下的数组已修改)。这就是为什么您最终得到错误结果的原因,即使您的 fmt.Println 语句显示在附加之前, temp 中所述,切片“只是”指向数组的指针、长度和容量。

因此,在您的情况下,由于 append([]int{}, temp...) 具有正确的值。

🎜当 🎜 创建一个新切片时,新切片内的值不可能发生变化,因为它没有被重用。🎜

以上是Go 中追加的奇怪行为的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:stackoverflow.com。如有侵权,请联系admin@php.cn删除