在新的 Swift API 设计指南中,协议常用的Type
后缀被删除了。虽然这对于独立的协议来说很容易做到(SequenceType
变得Sequence
),但我不确定如何更新我的API,其中协议为实现提供了基础。以下是来自流行框架的一些示例:
- Result μframework提供了
Result
,一个具体的成功/失败枚举,以及ResultType
,一个成功/失败类型的通用基本协议,Result
符合该协议。 - 反应性可可的主要类型是
Signal
和SignalProducer
,它们由SignalType
和SignalProducerType
支持。
在这两种情况下,大部分实现都在协议的扩展中,允许扩展使用类型约束的全部功能,并允许实现是泛型的。这与具有AnySequence
样式类型擦除类型的协议的情况不同:您实际上不需要自己实现这些协议,或者统一不同的类型。
我建议使用后缀Protocol
。这与标准库从协议中删除Type
后缀的方式一致,如 SE-0006 中所述:
在高级别上,这些变化可以总结如下。
- 从协议名称中删除
Type
后缀。在一些特殊情况下,这 意味着添加Protocol
后缀以摆脱类型名称 是主要的(尽管我们预计其中大多数会被淘汰 斯威夫特 3 种语言功能)。
例如,GeneratorType
被重命名为 IteratorProtocol
。
例如,Result 和 ReactiveSwift 也为 Swift 3 更新了 API。 ResultType
被重命名为 ResultProtocol
(在此提交中),SignalType
被重命名为 SignalProtocol
,SignalProducerType
被重命名为 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 {
// ...
}
因此,一旦支持参数化扩展,我们将能够取消此类协议。