追加一个整数切片到一个整数切片的切片会修改被追加的切片。

3
我正在尝试将整数切片附加到由整数切片组成的切片中。当我打印切片时,它显示出预期的结果。但是,当我将切片附加到切片的切片上时,内容会发生变化。
package main

import "fmt"

var myGraph [8][8]bool //the graph

var visited [8]bool //an array that marks if visited

var path []int //a slice to store a possible path

var paths [][]int

func dfs(src int, dest int) {
    //add current node to path
    path = append(path, src)

    //mark current node as visited
    visited[src] = true

    //if the current node is the destination
    //print the path and return
    if src == dest {
        fmt.Println(path)
        paths = append(paths, path) //I'm trying to push the path slice into the paths slice
        return
    }

    for i := 1; i <= 7; i++ { //loop through all nodes

        //if ith node is a neighbour of the current node and it is not visited
        if myGraph[src][i] && visited[i] == false {

            // call dfs on the current node
            dfs(i, dest)

            //mark the current node as unvisited
            //so that we can other paths to the final destination
            visited[i] = false

            //re-slice the slice - get rid of the current node
            path = path[:len(path)-1]
        }

    }

}

func main() {
    path = make([]int, 0, 8)
    paths = make([][]int, 0, 10)

    //creating the graph
    myGraph[1] = [...]bool{false, false, true, true, false, false, true, false}
    myGraph[2] = [...]bool{false, true, false, true, false, true, false, false}
    myGraph[3] = [...]bool{false, true, true, false, true, false, true, false}
    myGraph[4] = [...]bool{false, false, false, true, false, false, true, false}
    myGraph[5] = [...]bool{false, false, true, false, false, false, true, false}
    myGraph[6] = [...]bool{false, true, false, true, true, false, false, true}
    myGraph[7] = [...]bool{false, false, false, false, false, false, true, false}

    //call dfs by feeding in the source and the destination
    dfs(1, 7)
    fmt.Println(paths)
}

Output:
[1 2 5 6 7]
[1 3 2 5 6 7]
[1 3 4 6 7]
[1 3 6 7]
[1 6 7]
[[1 6 7 3 2 5] [1 6 7 3 2] [1 6 7 3 2] [1 6 7 3 2 5] [1 6 7 3 2] [1 6 7 3] [1 6 7]]

正如您所看到的,主函数在最后打印了切片的切片。然而,它的内容与dfs()打印的单独切片不同。

1个回答

1

让我们稍微修改一下这段代码:

var myGraph [8][8]bool //the graph

var visited [8]bool //an array that marks if visited

var path []int //a slice to store a possible path

var paths [][]int

func dfs(src int, dest int) {
    //add current node to path
    path = append(path, src)

    //mark current node as visited
    visited[src] = true

    //if the current node is the destination
    //print the path and return
    if src == dest {
        // (A)
        buffer := make([]int, len(path))
        copy(buffer, path)

        fmt.Println(buffer)
        paths = append(paths, buffer) //I'm trying to push the path slice into the paths slice

        // fmt.Println(path)
        // paths = append(paths, path) //I'm trying to push the path slice into the paths slice
        return
    }

    for i := 1; i <= 7; i++ { //loop through all nodes

        //if ith node is a neighbour of the current node and it is not visited
        if myGraph[src][i] && visited[i] == false {

            // call dfs on the current node
            dfs(i, dest)

            //mark the current node as unvisited
            //so that we can other paths to the final destination
            visited[i] = false

            //re-slice the slice - get rid of the current node
            path = path[:len(path)-1]
        }

    }

}

func main1() {
    // path = make([]int, 0, 8)
    // paths = make([][]int, 0, 10)

    //creating the graph
    myGraph[1] = [...]bool{false, false, true, true, false, false, true, false}
    myGraph[2] = [...]bool{false, true, false, true, false, true, false, false}
    myGraph[3] = [...]bool{false, true, true, false, true, false, true, false}
    myGraph[4] = [...]bool{false, false, false, true, false, false, true, false}
    myGraph[5] = [...]bool{false, false, true, false, false, false, true, false}
    myGraph[6] = [...]bool{false, true, false, true, true, false, false, true}
    myGraph[7] = [...]bool{false, false, false, false, false, false, true, false}

    //call dfs by feeding in the source and the destination
    dfs(1, 7)
    fmt.Println(paths)
}

现在它按预期工作了!为什么?因为切片是引用类型,而不是值类型;这意味着当您稍后更改 path 时,您将看到该新值,除非您像在 //(A) 处所做的那样对其进行快照。

谢谢。我猜测 fmt.Println 给出了期望的结果,因为它也是一种“快照”。 - Ruzaik
我是Go的新手,想知道是否有可能增强这个项目。我正在尝试编写一个函数,它将接受一个图形、源和目标,并输出路径片段。然而,现在我正在使用全局变量。我试图使用嵌套函数来实现,但似乎Go不允许这样做。有什么建议吗? - Ruzaik
1 - 下划线; fmt.Println将其参数发送到通道。在实际评估参数的时候,它们会被更改 - 在这种情况下,因为它们是引用类型。 - Kaveh Shahbazian
2 - 老实说,我并没有清晰地理解你在这里想要实现什么。但是Go语言有很好的处理图形的库。个人建议从一个节点结构开始,使用切片和数组可能会更有效,但在并发达到极限之后很难优化。 - Kaveh Shahbazian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接