Golang结构中的属性未修改 [英] Property in Golang struct not getting modified

查看:64
本文介绍了Golang结构中的属性未修改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我来自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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆