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(值)代码>回答:我们只在向下游传递一个值时才进行记忆。