如何扩展满足多重约束的协议 - Swift 2.0
Posted
技术标签:
【中文标题】如何扩展满足多重约束的协议 - Swift 2.0【英文标题】:How to extend a protocol that satisfies Multiple Constraints - Swift 2.0 【发布时间】:2015-09-16 12:38:15 【问题描述】:我正在尝试提供协议的默认实现,以便它可以满足来自其他协议的多个约束。
鉴于以下协议:
public protocol Creature
var name: String get
var canMove: Bool get
public protocol Animal: Creature
public protocol Moveable
var movingSpeed: Double get set
public protocol Agend
var aged: Int get
我可以在 Self
上使用单个条件进行扩展:
// all animals can move
extension Moveable where Self: Animal
public var canMove: Bool return true
但是如何设置约束来为同时符合Animal
和Aged
协议的类型提供默认的Moveable
实现?像下面这样的东西?还是 where 子句有一些“添加”“或”选项?
// Pseudocode which doesn't work
extension Moveable where Self: Animal && Self: Aged
public var canMove: Bool return true
【问题讨论】:
顺便说一下,要查看我编写的最终代码示例,请访问:audreyli.me/2015/06/29/… 【参考方案1】:你可以使用protocol composition:
extension Moveable where Self: protocol<Animal, Aged>
// ...
或者只是一个接一个地添加一致性:
extension Moveable where Self: Animal, Self: Aged
// ...
【讨论】:
这在它必须同时符合两者的情况下非常有用,但是如果您想检查一个或另一个的一致性怎么办?类似这样的东西:扩展 Movable where Self: protocol... @Dylan,这个语法不是检查一致性,而是用来表示一个类型符合一个协议。要检查协议的一致性,请查看 AirspeedVelocity 的答案***.com/questions/28124684/… 显然有一个新的语法,并且协议<..> 已被删除。在 Swift 4 中使用 & 语法。【参考方案2】:截至发文时,答案是使用protocol<Animal, Aged>
。
在 Swift 3.0 中,protocol<Animal, Aged>
已弃用。
在 Swift 3.0 中的正确用法是:
extension Moveable where Self: Animal & Aged
// ...
您还可以将协议与typealias
结合使用。当您在多个地方使用协议组合时,这很有用(避免重复并提高可维护性)。
typealias AgedAnimal = Aged & Animal
extension Moveable where Self: AgedAnimal
// ...
【讨论】:
我知道已经过去了一段时间,但是在 Objective-C 中不会遇到 typealias 类型(例如,用于检查协议一致性)。我最终这样做了:@objc public protocol AgedAnimal: Aged, Animal
【参考方案3】:
从 Swift 3 开始,您可以使用 typealias
创建符合多种协议的类型:
typealias AgedAnimal = Animal & Aged
所以你的代码会变成:
extension Moveable where Self: AgedAnimal
// ...
或者像这样:
typealias Live = Aged & Moveable
extension Animal where Self: Live
// ...
【讨论】:
以上是关于如何扩展满足多重约束的协议 - Swift 2.0的主要内容,如果未能解决你的问题,请参考以下文章