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



在新的 Swift API 设计指南中,协议常用的Type后缀被删除了。虽然这对于独立的协议来说很容易做到(SequenceType变得Sequence),但我不确定如何更新我的API,其中协议为实现提供了基础。以下是来自流行框架的一些示例:

  • Result μframework提供了Result,一个具体的成功/失败枚举,以及ResultType,一个成功/失败类型的通用基本协议,Result符合该协议。
  • 反应性可可的主要类型是SignalSignalProducer,它们由SignalTypeSignalProducerType支持。

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

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

在高级别上,这些变化可以总结如下。

  • 从协议名称中删除Type后缀。在一些特殊情况下,这 意味着添加Protocol后缀以摆脱类型名称 是主要的(尽管我们预计其中大多数会被淘汰 斯威夫特 3 种语言功能)。

例如,GeneratorType被重命名为 IteratorProtocol

例如,Result 和 ReactiveSwift 也为 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 {
    // ...
}

因此,一旦支持参数化扩展,我们将能够取消此类协议。

最新更新