Golang结构中的属性未被修改

Golang结构中的属性未被修改,go,Go,我来自Java,试图弄清楚Go的类型系统是如何工作的。我想创建一个简单的图形数据结构并实现广度优先搜索。这就是我目前所拥有的 package graph import "fmt" type Node struct { neighbors []Edge visited bool name string } type Edge struct { neighbor Node } type Graph struct { nodes []Nod

我来自Java,试图弄清楚Go的类型系统是如何工作的。我想创建一个简单的图形数据结构并实现广度优先搜索。这就是我目前所拥有的

package graph

import "fmt"

type Node struct {
    neighbors []Edge
    visited   bool
    name      string
}

type Edge struct {
    neighbor Node
}

type Graph struct {
    nodes []Node
}

func (g *Graph) addNode(node Node) {
    g.nodes = append(g.nodes, node)
}

func (n *Node) addEdge(neighbor Node) {
    edge := Edge{
        neighbor: neighbor,
    }
    n.neighbors = append(n.neighbors, edge)
}

func (g Graph) String() {
    for _, node := range g.nodes {
        //fmt.Printf("nodename: %v", node.name)
        fmt.Println(len(node.neighbors))
        if len(node.neighbors) > 0 {
            fmt.Print("node: %v, edges: ", node.name)
            for _, e := range node.neighbors {
                fmt.Print(e.neighbor.name)
            }
        }
    }
}
当我尝试使用测试代码运行它时:

func TestGraph(t *testing.T) {
    graph := Graph{}
    n1 := Node { name: "abc", }
    n2 := Node { name: "def", }
    graph.addNode(n1) 
    graph.addNode(n2) 
    n1.addEdge(n2)

    graph.String()
}

在my String()方法中,len(node.neights)始终为0。我做错了什么?我认为,由于我在addEdge中引入了引用类型,它修改了节点引用,但我显然遗漏了Go的类型系统

这不是类型系统问题,而是Go中如何传递数据的问题

我认为根本的误解是关于“参照传递”。在Go中,所有内容都是按值传递的,没有按引用传递()

因此,当您将
节点
结构传递到
addEdge
方法时,它实际上是在复制该结构

如果希望引用相同的基础结构而不是复制它,则应将指针传递给它

尝试以下稍微修改的代码,该代码使用指针传递结构:(您可以在此处调整并运行代码:)


这不是类型系统问题,而是Go中如何传递数据的问题

我认为根本的误解是关于“参照传递”。在Go中,所有内容都是按值传递的,没有按引用传递()

因此,当您将
节点
结构传递到
addEdge
方法时,它实际上是在复制该结构

如果希望引用相同的基础结构而不是复制它,则应将指针传递给它

尝试以下稍微修改的代码,该代码使用指针传递结构:(您可以在此处调整并运行代码:)


您需要通过指针传递变量,否则将创建一个新值

 func (g *Graph) addNode(node *Node) {
    g.nodes = append(g.nodes, node)
 }

 ...
 n1 := Node { name: "abc", }
 graph.addNode(&n1)
 ...
 n1.addEdge(&n2)

您需要通过指针传递变量,否则将创建一个新值

 func (g *Graph) addNode(node *Node) {
    g.nodes = append(g.nodes, node)
 }

 ...
 n1 := Node { name: "abc", }
 graph.addNode(&n1)
 ...
 n1.addEdge(&n2)
FWIW
String()
通常是一个满足
fmt.Stringer
()接口的方法
String()
。大多数Go程序员会惊讶地看到一个不返回字符串的
String()
,而FWIW
String()
通常是一个满足
fmt.Stringer
接口的方法
String()
。大多数Go程序员会惊讶地看到一个不返回字符串的
String()