当传递一个序列而不是一个集合时,为什么set# intersection的行为不同?



我注意到一个应用程序中的一个奇怪的错误,并将其缩小到一个令人惊讶的原因:如果你传递一个序列到Set#intersection,你会得到不同的行为,如果你传递一个Set,即使两者都是Set数据结构的支持方法。

你可以在任何Swift REPL中验证:

1> Set([3, 6, 0, 1, 5, 2, 4]).intersection([0, 1, 1, 2, 3, 4, 5])
$R0: Set<Int> = 7 values {
[0] = 5
[1] = 0
[2] = 3
[3] = 1
[4] = 2
[5] = 6
[6] = 4
}
2> Set([3, 6, 0, 1, 5, 2, 4]).intersection(Set([0, 1, 1, 2, 3, 4, 5]))
$R1: Set<Int> = 6 values {
[0] = 1
[1] = 5
[2] = 0
[3] = 4
[4] = 2
[5] = 3
}

这里的问题是,第一个结果有一个额外的值,整数6,即使在传递给intersection的序列中没有6。第二个结果是正确的,第一个是错误的。这两次调用之间的唯一区别是,第二次调用将其序列转换为Set

是我疯了,还是这是意外的行为?

我认为这是SR-16061的bug。该报告显示了与您的报告类似的意外行为,其中使用intersectionSet过载产生正确的输出,但Sequence过载却没有。

let s = Set("ae")
print("s: (s)") // ["a", "e"]
let i = s.intersection("aa")
let j = s.intersection(Set("aa"))
print("i: (i)") // ["a", "e"]
print("j: (j)") // ["a"]
我试着调查一下发生了什么事。上一次修改NativeSet.swift中intersection方法的提交是在2021年11月。这与Swift版本的发布日期一致,这个错误可以在Swift 5.5和5.6之间重现。据说这个改变应该通过使用位集来加速Set.intersection

最新更新