当前位置: 首页 > 面试题库 >

Golang结构中的属性未修改

陶睿
2023-03-14
问题内容

我来自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()
    }

在我的String()方法中,len(node.neighbors)始终为0。我在做什么错?我以为,因为我在addEdge中采用了引用类型,所以它修改了节点引用,但显然我缺少有关Go的类型系统的信息。


问题答案:

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

我认为根本的误解是关于“通过引用”。在Go中,所有内容均按值传递,没有按引用传递(https://golang.org/doc/faq#pass_by_value)

因此,当您将一个Node结构传递给该addEdge方法时,它实际上是在复制该结构。

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

尝试以下使用指针传递结构的稍作修改的代码:(您可以在此处调整并运行代码: 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修改结构体中的切片值方法,包括了golang修改结构体中的切片值方法的使用技巧和注意事项,需要的朋友参考一下 golang修改结构体中的切片值,直接传结构体地址就可以 到此这篇关于golang修改结构体中的切片值方法的文章就介绍到这了,更多相关golang 修改结构体切片值内容请搜索呐喊教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持呐喊教程!

  • 问题内容: 我正在使用JSON将一些值从外部源获取到变量中。 我有一个这样的类型,将值放入: 解组后,我可以通过以下方式访问类型: 但是如果我尝试做类似的事情: 编译器抱怨没有这样的值。 所以我的问题是,我如何根据某些条件引用我知道会存在的Go属性? 做到这一点: 但这不是很灵活,因为我将收到不同的。 问题答案: 会尽力将数据放置在最适合您的类型的位置。从技术上讲,您的第一个示例将起作用,但是即使

  • 问题内容: 可以在Golang中定义一个不变的结构吗?一旦初始化,则只能对struct的字段进行读取操作,而无需修改字段值。如果是这样,该怎么做。 问题答案: 通过使其成员不导出并提供阅读器,可以在其程序包外部将结构设为只读。例如: 和用法:

  • Go 语言中的结构体和 C 语言中结构体一样,都是用来保存一组 不同类型的数据 Go 语言中的结构体和 C 语言中结构体一样,都需要先定义结构体类型再利用结构体类型定义结构体变量 定义结构体类型 type 类型名称 struct{ 属性名称 属性类型 属性名称 属性类型 ... ... } type Studentstruct { name string age int

  • 我需要在DTO上有一个类似idEncrypted的属性,因为它们只能通过加密的方式传递给我,但是,我需要映射在DB上找到的解密id。我已经有了一个解密方法,但我不知道如何映射它并忽略idEncrypted。 我不知道在哪里做转换

  • 我已经在stackoverflow和网络上寻找解决方案。我没有见过有效的解决方案,因为可能没有一个帖子完全符合我的用例,它包含文件中的列表和对象结构。 这里有一个例子作为yaml 这是与属性文件相同的示例 我希望能够向我的应用程序提供 teddy.yml 或 teddy.properties 文件以进行配置。 这是我的课程: 我已经尝试了这种设置,使用环境来尝试访问属性,删除前缀,声明一个“Pro