Golang结构中的属性未修改 [英] Property in Golang struct not getting modified
问题描述
我来自Java,试图弄清楚Go的类型系统是如何工作的.我想创建一个简单的图形数据结构并实现广度优先搜索.这就是我到目前为止所拥有的.
I'm coming from Java and trying to figure out how Go's type system works. I want to create a simple graph data structure and implement breadth first search. This is what I have so far.
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)
}
}
}
}
当我尝试使用测试代码运行它时:
when I try to run it with test code:
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()
}
在我的String()方法中,len(node.neighbors)始终为0.我在做什么错?我以为,因为我在addEdge中采用了引用类型,所以它修改了节点引用,但是显然我缺少有关Go的类型系统的信息.
in my String() method, the len(node.neighbors) is always 0. What am I doing wrong? I thought that since I take in a reference type in addEdge, it modifies the node reference but I'm obviously I'm missing something about Go's type system.
推荐答案
这不是类型系统问题,而是有关如何在Go中传递数据的问题.
This isn't a type system issue, but an issue with how data is passed in Go.
我认为根本的误解是关于通过引用传递".在Go中,所有内容都是按值传递的,没有按引用传递的内容( https://golang.org/doc/faq#pass_by_value )
I think the root misunderstanding is about "passing by reference". In Go, everything is passed by value, there is no pass by reference (https://golang.org/doc/faq#pass_by_value)
因此,当您将Node
结构传递给addEdge
方法时,实际上是在复制该结构.
So when you pass a Node
struct in to the addEdge
method, it's actually making a copy of that struct.
如果要引用相同的基础结构而不是复制该结构,则应将指针传递给它.
If you want to refer to the same underlying struct instead of copying it you should pass the pointer to it.
请尝试使用指针传递以下结构的以下经过稍微修改的代码:(您可以在此处调整并运行代码:
Try the following slightly modified code, that uses pointers to pass the structs: (You can tweak and run the code here: https://play.golang.org/p/Qsbi4LBXS4)
package main
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.Printf("number of neighbors: %d\n", len(node.neighbors))
if len(node.neighbors) > 0 {
fmt.Printf("node: %v, edges: ", node.name)
for _, e := range node.neighbors {
fmt.Printf("%q", e.neighbor.name)
}
fmt.Println()
}
}
}
func main() {
graph := &Graph{}
n1 := &Node{name: "abc"}
n2 := &Node{name: "def"}
graph.addNode(n1)
graph.addNode(n2)
n1.addEdge(n2)
graph.String()
}
这篇关于Golang结构中的属性未修改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!