dictionary - 计算递归定义的自定义类型的不同对象数量的惯用方法

标签 dictionary recursion go set equality

据我了解,我无法在 Go 中为用户定义的类型定义相等性。那么计算某些自定义类型(可能递归定义)的不同对象数量的惯用方法是什么?这是我正在尝试做的事情的示例。

package main

import "fmt"

type tree struct {
    left  *tree
    right *tree
}

func shapeOf(a tree) string {
    temp := "{"
    if a.left != nil {
        temp += shapeOf(*(a.left))
    }
    temp += "}{"
    if a.right != nil {
        temp += shapeOf(*(a.right))
    }
    temp += "}"
    return temp;
}

func main() {
    a := tree{nil, nil}
    b := tree{nil, &a}

    c := tree{nil, nil}
    d := tree{nil, &c}

    e := tree{nil, nil}
    f := tree{&e, nil}

    s := make(map[string]bool)

    s[shapeOf(b)] = true
    s[shapeOf(d)] = true
    s[shapeOf(f)] = true
    fmt.Println(len(s)) // As required, prints 2 because the first two trees have the same shape
}

它可以工作,但是字符串的使用非常丑陋,而且可能效率也很低。显然,我可以轻松地编写一个递归方法来判断两棵树是否相等——类似于

func areEqual(a, b tree) bool

但这并不能使我将树用作 map 键。执行此类操作的惯用 Go 方法是什么?

最佳答案

你不能为用户定义的类型定义相等性,因为它已经被 go 定义了。基本上,所有关于它的知识都在 comparable 中进行了解释。部分。

短篇小说:如果可以比较两个结构值的字段(没有 slice 、映射或函数),则可以比较它们。对于相等性也是一样:如果两个结构体的字段相等,则它们是相等的。在您的情况下,问题是为了比较指针,Golang 比较内存地址,而不是它们指向的结构。

那么,是否可以计算某个结构的不同值?是,如果结构不包含嵌套的 slice 、映射、函数或指针。对于递归类型,这是不可能的,因为你不能定义这样的东西:

type tree struct {
    left tree
    right tree
}

测试递归类型相等性的惯用方法是使用 reflect.DeepEqual(t1, t2 interface{}),因为它遵循间接寻址。但是,这种方法效率低下,因为使用了大量的反射。就您而言,我认为没有任何简洁优雅的解决方案可以满足您的需求。

关于dictionary - 计算递归定义的自定义类型的不同对象数量的惯用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37348901/

相关文章:

python - 按推送顺序存储 Python 字典条目

python - 如何根据键的第一个元素(元组)对字典进行排序

javascript - 在 AngularJS 中解析字典

recursion - Coq新手: How to iterate trough binary-tree in Coq

regex - 网址正则表达式调整以仅捕获 url 而不是 ip

java - 使用 XStream 将 XML 转换为 Java Map<String, Integer>

java - 递归方法在某些分支上过早停止

recursion - 查找并删除列表中最后一次出现的指定元素 [racket]

mongodb - 如何确保 goroutine 在退出前完全运行

javascript - 在 HTML 页面上使用 Golang 进行实时搜索