如何扩展满足多重约束的协议 - Swift 2.0

How to extend a protocol that satisfies Multiple Constraints - Swift 2.0

我正在尝试提供协议的默认实现,以便它可以满足来自其他协议的多个约束。

给定以下协议:

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 }
}

但是我如何设置约束来为同时符合 AnimalAged 协议的类型提供默认的 Moveable 实现?像下面这样的东西?还是 where 子句有一些“添加”“或”选项?

// Pseudocode which doesn't work
extension Moveable where Self: Animal && Self: Aged {
    public var canMove: Bool { return true }
}

您可以使用 protocol composition

extension Moveable where Self: protocol<Animal, Aged> {
    // ... 
}

或者只是一个接一个地添加一致性:

extension Moveable where Self: Animal, Self: Aged {
    // ... 
}

截至本文 post 时,答案是使用 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 {
    // ... 
}

从 Swift 3 开始,您可以使用 typealias 创建符合多种协议的类型:

typealias AgedAnimal = Animal & Aged

因此您的代码将变为:

extension Moveable where Self: AgedAnimal {
    // ...
}

或者像这样:

typealias Live = Aged & Moveable

extension Animal where Self: Live {
    // ...
}

使协议成为引用类型

extension Moveable: AnyObject {}