请提供一个实际示例,说明如何/为何在Swift中使用SinkOf和SinkType(标准库的一部分)?

Sam*_*Sam 2 reactive-programming swift

这些在ReactiveCocoa的Swift实现和我遇到的任何其他功能反应库中大量使用,因此从这个角度来看似乎很有意义.

它本质上似乎是一个包含通用值的结构,但这显然过于简单化了解释.这些类型在swift标准库中有一些注释,但我发现它们有点太模糊,谷歌收益很少.

小智 7

我认为将水槽视为发电机的对应物会有所帮助.

生成器基本上是一个函数(Void -> T),在哪里T是你生成的东西的类型. GeneratorType是一个允许结构和类等作为生成器的协议,通过给该函数命名:next() -> T.这很方便,因为生成器函数不带参数,因此要生成有用的值序列,需要一个位置来跟踪调用之间的某些状态. Generator<T>是一个符合GeneratorType协议的通用基类型,您可以继承它以实现自己的协议GeneratorType.

所以,回到水槽.接收器是发生器的反转,意味着它是一个函数(T -> Void).它还有一个相关的协议SinkType,它允许结构和类通过定义接收器函数作为接收器put(T).还有一个基本实现SinkOf<T>,您可以通过将put函数的实现作为闭包传递而直接使用而无需进行子类型化.由于接收函数返回Void,它不太可能需要内部状态,但如果这样做,您可以继承SinkOf或实现SinkType您自己的类/结构.

因此,SinkOf它并没有完全包装泛型值,因为它包含了一个带有泛型值并对其执行某些操作的函数.在即将推出的ReactiveCocoa 3重写中,它们被用来取代"订户"的RAC 2概念.

在RAC 2,信号通过调用输出事件sendNext:,sendError:以及sendCompleted实现该目的的方法RACSubscriber的协议.RAC 3替换的水槽的单独的方法Events,其中一个Event<T,ErrorType>是一个枚举,可以是其中一种情况下.Next(T),.Error(ErrorType)以及.Completed,加上新.Interrupted的情况.

在单个枚举中包含所有事件类型可以更清楚地了解信号的全部内容:它是一个事件流.事件一次到达一个,可以是四种类型之一(RAC2中有三种).如果没有swift enum类型,则必须单独调度这些事件,因为与事件关联的值的类型对于每种事件类型都是不同的.随着enums表示可以携带不同类型的值,所有你需要实现RACSubscriber是一个地方put的Event,或者换句话说,一个接收器.

这仍然留下了为什么要打扰SinkType而不是仅仅传递类型的闭包的问题(T -> Void).文档只讨论编译器优化的好处,但我个人认为它很有用,因为它为您提供了一个可以使用的名称.如果我看到一个关闭(T -> Void),我必须暂时停下来解析这些类型,如果我一直在传递它们,那么很多parens和箭头会使我的定义混乱.

另外,如果您正在使用发电机,这是一个很好的概念匹配.由于RAC Signal在概念上是事件的发生器,因此根据汇集来说话是有意义的,汇集是发电机的自然补充.