据我了解,我无法在Go中定义用户定义类型的相等性。那么计算某些自定义类型(可能递归定义)的不同对象数量的惯用方法是什么呢?这是我想要做的事情的一个例子。
public static Collection<Order> readFromFile(String filePath) throws IOException {
Map<String, Order> orderMap = new LinkedHashMap<>();
List<String> lines = Files.readAllLines(Paths.get(filePath));
它可以工作,但字符串的使用非常难看,而且效率也很低。显然,我可以轻松编写一个递归方法来判断两棵树是否相等 - 比如
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
}
但是这不能让我使用树作为地图键。做这样的事情的惯用Go方式是什么?
答案 0 :(得分:1)
您无法为用户定义的类型定义相等性,因为它已由go定义。基本上,所有有关它的信息都在comparable部分进行了解释。
简短的故事:如果可以比较它们的字段(没有切片,地图或函数),则可以比较两个结构值。同样的事情是平等:如果两个结构的字段相等,它们是相等的。在你的情况下,问题是,为了比较指针,Golang比较内存地址,而不是它们指向的结构。
那么,是否可以计算某个结构的不同值?是的,如果struct不包含嵌套切片,map,function或pointer。对于递归类型,这是不可能的,因为你不能定义这样的东西:
type tree struct {
left tree
right tree
}
测试递归类型相等性的惯用方法是使用reflect.DeepEqual(t1, t2 interface{})
,因为它遵循间接性。然而,这种方法效率低,因为使用了大量反射。在您的情况下,我认为没有任何干净而优雅的解决方案可以满足您的需求。