如何根据Swift API设计指南调整协议/实现对?

23
在新的 Swift API 设计指南 中,常用的协议后缀 Type 被取消了。虽然对于独立的协议很容易做到这一点(例如将 SequenceType 更改为 Sequence),但我不知道如何更新协议为实现提供基础的 API。以下是一些流行框架的示例:
  • Result µframework 提供了 Result,一个具体的成功/失败枚举,以及 ResultType,一个成功/失败类型的通用基础协议,Result 符合该协议。
  • ReactiveCocoa 的主要类型是 SignalSignalProducer,它们由 SignalTypeSignalProducerType 支持。

在这两种情况下,大部分实现都在协议的扩展中,允许扩展使用类型约束的全部功能,并允许实现是通用的。这与具有 AnySequence 样式的类型擦除不同:你不会真正期望自己实现这些协议,或者统一不同的类型。


我已经给这个问题添加了赏金,因为我想要一个(明确的)答案。 - Tom Knapen
1个回答

21
我建议使用后缀Protocol。这与标准库从协议名称中去除Type后缀的方式一致,如SE-0006中所述:

在高层次上,更改可以总结如下。

  • 从协议名称中去除Type后缀。在一些特殊情况下, 这意味着添加Protocol后缀以避免主要类型名称 (尽管我们预计大多数这样的类型将被Swift 3语言功能所淘汰)。
例如,GeneratorType被重命名为IteratorProtocol
此外,例如ResultReactiveSwift都已经为Swift 3更新了它们的API。 ResultType被重命名为ResultProtocol(在此提交中),SignalType被重命名为SignalProtocolSignalProducerType被重命名为SignalProducerProtocol(在此提交中)。
虽然值得注意的是,在绝大多数情况下,这样的协议仅存在作为缺乏参数化扩展的解决方法。
例如,我们目前无法说:
struct SomeGenericThing<T> {
    var value: T
}

extension <T> Array where Element == SomeGenericThing<T>, T : Comparable {

}

但是引入协议使我们能够将通用的占位符实现为关联类型,然后我们可以在约束中使用它们:

protocol SomeGenericThingProtocol {
    associatedtype T
    var value: T { get set }
}

struct SomeGenericThing<T> : SomeGenericThingProtocol {
    var value: T
}

extension Array where Element : SomeGenericThingProtocol, Element.T : Comparable {
    // ...
}

因此,一旦支持参数化扩展,我们就能够摆脱这些协议。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接