Swift 移除复制的联合框架的奇怪行为

Swift 移除复制的联合框架的奇怪行为,swift,combine,Swift,Combine,考虑: let test = [(1,true), (2,false), (3,false), (4,true), (5,true), (6,true)] test.publisher.removeDuplicates { $0.1 != $1.1 } .sink { print($0.0) } 这是(Int,Bool)对的序列。在我的RemovedUpplicates过滤器中,我想说的是:“不要让布尔值从上一个布尔值更改的任何对通过。” 因此,我所期望的是: 2无法通过,因为它的f

考虑:

let test = [(1,true), (2,false), (3,false), (4,true), (5,true), (6,true)]
test.publisher.removeDuplicates { $0.1 != $1.1 }
    .sink { print($0.0) }
这是(Int,Bool)对的序列。在我的
RemovedUpplicates
过滤器中,我想说的是:“不要让布尔值从上一个布尔值更改的任何对通过。”

因此,我所期望的是:

  • 2
    无法通过,因为它的
    false
    与前面的
    true

  • 4
    无法通过,因为它的
    true
    与前面的
    false

所有其他的都应该通过,所以结果应该是
1,3,5,6

但事实并非如此。它是
1,4,5,6

有人能解释为什么吗?
removeDuplicates
在这里使用什么推理

我想我知道答案;我认为这是将上游的当前值与允许通过过滤器的前一个值进行比较。因此,
1
通过它的
true
,然后
2
3
被抑制,因为它们的
false
与之不同

但这肯定不对吗?当然,我们应该与来自上游的先前值进行比较


[文档事实上对此有点奇怪。他们说“只发布与上一个元素不匹配的元素”。我假设这意味着“来自上游的上一个元素”。但它似乎是指“我们实际发布到下游的上一个元素”?]RemovedUpplicates的行为与它的祖父Rx.NET的
DistinctUntilChanged的行为相匹配,您可以查看其源代码


在“相等”值“a,a,a,…”的流中,将每个新的“a”存储为先前的值需要复制该值,并且可能需要调整引用计数(如果它是具有引用属性的值类型)。坚持第一个“a”可以避免这项工作。

你的假设完全正确。如果在比较闭包中放置一个
打印
,那么您将看到它正是发生的事情。我认为这也是有道理的,因为它确保了下游不会有重复。奇怪的是,你的比较是一个不平等的东西,可能应该是一个平等的测试duplication@NewDev当然,这是一个奇怪的测试,但我就是这样遇到的。如果你没有在闭包中加入一些有趣的东西,你就不会得出“上一个来自上游”和“上一个传递到下游”之间的区别。这就是我想知道的(即is
.removeDuplicates
正确地建模它的“继承”行为)。我所追求的关键是解决之前价值的模棱两可问题。我假设它是从上游传来的,但它似乎意味着从下游传来的。在您指向的源代码中,它看起来像是行
\u currentKey=key;ForwardOnNext(值)回答:我们只在向下游传递一个值时才进行记忆。