为了账号安全,请及时绑定邮箱和手机立即绑定

Go 变量被覆盖(错误?)

Go 变量被覆盖(错误?)

Go
慕婉清6462132 2021-07-02 14:00:44
这里有点奇怪。我的问题是,人们运行我的代码会得到和我一样的结果吗?如果你这样做了,是我的代码有问题(我通常是一个 python 程序员),还是 golang 中的错误?系统信息:围棋版本(1.1.2)的Linux的x64(Fedora的19)代码的背景信息:我正在做的是找到从三角形顶部到底部的最高成本路线,这是来自 project_euler 18 和 67该bug:我设置了一个名为pathA变量,这是一个整数列表,加上新价值新的int从三角形如3,7,2追加8中应该等于3,2,7,8,但它确实!......直到我设置pathB。pathB被设置正确但是突然pathA是相同的值pathB。tl;dr当我设置另一个变量时,一个变量被覆盖我的代码如下:package mainimport (    "fmt")func extendPaths(triangle, prePaths [][]int) [][]int {    nextLine := triangle[len(prePaths)]    fmt.Println("#####PrePaths: ", prePaths)    fmt.Println("#####nextLine: ", nextLine)    postPaths := [][]int{{}}    for i := 0; i < len(prePaths); i++ {        route := prePaths[i]        nextA := nextLine[i]        nextB := nextLine[i+1]        fmt.Println("Next A:", nextA, "Next B:", nextB, "\n")        pathA := append(route, nextA)        fmt.Println("pathA check#1:", pathA)        pathB := append(route, nextB)        fmt.Println("pathA check#2:", pathA, "\n")        postPaths = append(postPaths, pathA)        postPaths = append(postPaths, pathB)    }    postPaths = postPaths[1:]    prePaths = [][]int{postPaths[0]}    for i := 1; i < len(postPaths)-1; i += 2 {        if getSum(postPaths[i]) > getSum(postPaths[i+1]) {            prePaths = append(prePaths, postPaths[i])        } else {            prePaths = append(prePaths, postPaths[i+1])        }    }    prePaths = append(prePaths, postPaths[len(postPaths)-1])    return prePaths}func getSum(sumList []int) int {    total := 0    for i := 0; i < len(sumList); i++ {        total += sumList[i]    }    return total}func getPaths(triangle [][]int) {    prePaths := [][]int{{triangle[0][0]}}    for i := 0; i < len(triangle)-1; i++ {        prePaths = extendPaths(triangle, prePaths)    }}func main() {    triangle := [][]int{{3}, {7, 4}, {2, 4, 6}, {8, 5, 9, 3}}    getPaths(triangle)}
查看完整描述

1 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

切片基本上是由 3 件事组成的结构:

  1. 指向切片中元素数组的指针

  2. 该数组的长度(“容量”)

  3. 数组中实际存储的元素数(“长度”)

当您运行以下代码时:

append(x, element)

它执行以下操作:

  1. 检查扩展切片是否会超出底层数组的容量。如果是这样,分配一个更大的并将现有元素复制到新数组,并更新容量。

  2. 将新元素(或多个元素)写入数组的末尾并更新长度。

  3. 返回新切片。

在您的代码中,您有以下内容:

pathA := append(route, nextA)
pathB := append(route, nextB)

现在这里有两种可能:

  1. len(route) == cap(route),并且将分配一个新的支持数组,pathApathB具有独立的值。

  2. len(route) < cap(route),所以pathApathB最终共享相同的背衬阵列。数组中的最后一个元素将是nextB,因为该操作是第二次运行的。

对于循环的前几次迭代,第一种情况似乎是正确的,之后您遇到了第二种情况。您可以通过手动为其中一个路径制作副本来避免这种情况(使用 分配一个切片make(),然后用于copy()复制旧数据)。


查看完整回答
反对 回复 2021-07-12
  • 1 回答
  • 0 关注
  • 232 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信