如何扩展满足多重约束的协议 - 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 

但是如何设置约束来为同时符合AnimalAged 协议的类型提供默认的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&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 
    // ...

【讨论】:

以上是关于如何扩展满足多重约束的协议 - Swift 2.0的主要内容,如果未能解决你的问题,请参考以下文章

无法同时满足约束 - Swift

Swift:无效参数不满足:约束

swift 学习- 24 -- 协议 01

在 Swift 中声明具有类型约束的属性

如何在 Swift 2.0 中获得正确的 UIView 大小或边界?

两种改进的模拟退火算法求解大值域约束满足问题2.0