【发布时间】:2019-03-31 06:30:06
【问题描述】:
我的问题与this question 略有不同,后者询问如何检查 Go 切片的相等性。
就像article 建议的那样,Go 切片是一个 值,由三部分组成:指向数组的指针、段的长度和它的容量(段的最大长度)。那么是否可以(便宜地)检查两个这样的切片是否相等,因为它们指向同一个底层数组并且具有相同的长度和容量值(最好不遍历两个切片检查单个元素的相等性)?看来== 运算符没有在切片上定义。
当我实现一个位向量 (IntSet) 时,问题出现了,它在内部使用 []uint64 来表示元素,我偶然发现实现了一个 方法 func (*IntSet) Equals(that *IntSet) bool,它可以被称为喜欢s.Equals(s)。
(看来我可以针对这种情况进行优化,如下所示,但问题仍然存在:
func (this *IntSet) Equals(that *IntSet) bool {
if this == that { // use equality of pointers!
return true
}
// omitted for brevity
}
【问题讨论】:
-
根据该定义,
[]int{1, 2, 3} == []int{1, 2, 3}为假。似乎语言作者决定在切片上未定义相等运算符,而不是让特定的潜在错误点。 -
@TimCooper 我认为这是可以理解的,因为它们实际上是两个不同的切片 值,它们恰好具有相同的元素。
-
golang.org/ref/spec#Comparison_operators 讨论了
==d 可以是什么(切片可以检查== nil,但不能相互检查)。作为语言设计师,我还猜想人们可能期望两个切片具有相同的值(即使在完全独立的数组中),它们是==,在某些情况下,即使是简单的值比较也可能会出现不一致的行为底层数组可能会或可能不会重新分配。