在Swift中,elementsEqual和'=='有什么区别?

6

我正在学习Swift标准库,看到了一个方法elementsEqual用于比较序列。

我不太明白这个函数的价值所在,因为它只会在顺序完全相同的情况下返回true。如果它可以告诉我两个序列是否包含相同的元素,而这些元素恰好处于不同的顺序中,那么它就会有一些用处,因为这可以避免我自己进行排序的麻烦。

这就引出了我的问题:

使用elementsEqual和'=='在比较两个序列时有什么区别吗?它们之间有优缺点吗?

我写了以下测试程序:

let values = [1,2,3,4,5,6,7,8,9,10] let otherValues = [1,2,3,4,5,6,7,8,9,10] values == otherValues values.elementsEqual(otherValues)

这两个检查结果都为true,因此我无法辨别它们之间的区别。


1
序列类型没有 == 运算符。 - Martin R
@MartinMuldoon 这与 === 无关。 - rmaddy
@MartinR 但是 let aa = 1...3 let bb = 1...3 if aa == bb { print("hello") } 是可以工作的。 - rmaddy
还有一个用于可比较元素的数组==运算符:https://developer.apple.com/documentation/swift/1539758,这就是`values == otherValues`所调用的。 - Martin R
为什么需要有区别呢?这只是语法糖...在Swift中恰好起作用,甚至可能在其他一些语言中也是如此。你可以问同样的问题来解释循环,所有编程语言都包含了不同的循环语句方式,有些微妙地不同于其他语言,而有些则看起来相同。但是,为什么不测试一下自己的问题呢?比如说性能;创建一个包含100万个数字的集合,使用两个运算符进行比较,看看它们是否以相同的速度返回! - user3069232
显示剩余3条评论
1个回答

5

在研究了一段时间后,我找到了一个实际的例子来解释下面原始答案的区别:使用 elementsEqual 可以比较不同类型的集合,如 Array RandomAccessSlice Set ,而使用 == 则不能这样做:

let array = [1, 2, 3]
let slice = 1...3
let set: Set<Int> = [1, 2, 3] // remember that Sets are not ordered

array.elementsEqual(slice) // true
array.elementsEqual(set) // false
array == slice // ERROR
array == set // ERROR

关于这个问题的不同之处,@Hamish在下面的评论中提供了实现的链接,为了更好的可见性,我将分享这些链接: 我的原始答案: 这里有一个示例playground,可以说明它们之间的差异:
import Foundation

struct TestObject: Equatable {
    let id: Int
    static func ==(lhs: TestObject, rhs: TestObject) -> Bool {
        return false
    }
}

// TestObjects are never equal - even with the same ID
let test1 = TestObject(id: 1)
let test2 = TestObject(id: 1)
test1 == test2 // returns false

var testArray = [test1, test2]
var copiedTestArray = testArray

testArray == copiedTestArray // returns true
testArray.elementsEqual(copiedTestArray) // returns false

也许有人知道确切答案,但我猜测==大概会计算出memoryLocationIsEqual || elementsEqual(在比较内存地址相等后停止计算),而elementsEqual则跳过了内存地址部分,这使得==更快,但elementsEqual更可靠。

1
你的==实现违反了Equatable的语义要求(即它不是自反的),因此预计会出现意外行为。 - Hamish
你说得对,预期之外的行为是可以预料到的,我目前想不出一个好的例子来说明这种情况何时会发生。但是,我的回答是有效的 Swift 代码,并且它是 OP 的问题的答案:“在比较两个序列时,使用 elementsEqual 和 '==' 有什么区别吗?” - Benno Kress
@Hamish 是的,你说得完全正确。我的原始回答中的代码永远不应该投入生产。尽管如此,它展示了两个函数“==”和“elementsEqual”的根本区别,我想证明这一点,因为上面的注释(只是语法糖等)绝对是错误的。自从你最后一次评论以来,我已经更新了我的答案,并提供了另一种解决问题的方法。 - Benno Kress
@Hamish 不错,没想到在那里找...现在已经很晚了 :D - Benno Kress
1
@RDSpinz 现在添加了另一个(更好的)示例,使用RandomAccessSlice,它会评估为true,因为它有顺序;) - Benno Kress
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接