据我了解,我无法在 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/