【问题标题】:How to extend a protocol that satisfies Multiple Constraints - Swift 2.0如何扩展满足多重约束的协议 - 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 }
}

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

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

【问题讨论】:

标签: protocols swift2


【解决方案1】:

你可以使用protocol composition

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

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

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

【讨论】:

  • 这在它必须同时符合两者的情况下非常有用,但是如果您想检查一个或另一个的一致性怎么办?类似这样的东西:扩展 Movable where Self: protocol...
  • @Dylan,这个语法不是检查一致性,而是用来表示一个类型符合一个协议。要检查协议的一致性,请查看 AirspeedVelocity 的答案stackoverflow.com/questions/28124684/…
  • 显然有一个新的语法,并且协议<..> 已被删除。在 Swift 4 中使用 & 语法。
【解决方案2】:

截至发文时,答案是使用protocol&lt;Animal, Aged&gt;

在 Swift 3.0 中,protocol&lt;Animal, Aged&gt; 已弃用。

在 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 {
    // ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    相关资源
    最近更新 更多