为什么 Set#intersection 在传递 Sequence 而不是 Set 时表现不同?

Why does Set#intersection behave differently when passed a Sequence instead of a Set?

提问人:Bill 提问时间:6/11/2022 更新时间:6/12/2022 访问量:57

问:

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

您可以在任何 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
}

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

是我失去了理智,还是这是意想不到的行为?

快速 设置 序列

评论

0赞 Sweeper 6/11/2022
您使用的是哪个版本的 Swift?我无法在 Swift 5.5.1 上重现此内容。
0赞 Bill 6/11/2022
5.6.1 以及新的测试版 5.7
0赞 Sweeper 6/11/2022
似乎与此错误相同
2赞 matt 6/12/2022
这是一个严重的错误!有人需要改进他们的单元测试。但是,解决方法是微不足道的。

答:

1赞 Sweeper 6/12/2022 #1

我认为这是错误 SR-16061。该报告显示与你的意外行为类似的意外行为,其中使用重载 of 会生成正确的输出,但重载不会。SetintersectionSequence

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 中方法的提交是在 2021 年 11 月。这与可以重现此错误的 Swift 版本的发布日期一致 - 仅在 Swift 5.5 和 5.6 之间。据说这种变化应该通过使用位集来加快速度。intersectionSet.intersection