Swift 4 协议(protocol)组合一致性

标签 swift swift4

<分区>

[首先,如果有人对问题有更好的名称,建议就会被很好地接受。到目前为止,我没有为这个问题找到更好的名称。]

所以,这就是问题。

假设我有一个协议(protocol) ProtocolA、一个协议(protocol) ProtocolB 和一个协议(protocol) ProtocolX 定义如下:

protocol ProtocolA {
  func doSomethingA()
}

protocol ProtocolB {
   func doSomethingB()
}

protocol ProtocolX {
   var handler: ProtocolA { get }
}

然后我在我的 ProtocolX 类中有一个正确的实现如下:

class Donald: ProtocolX {
   ...
   var handler: ProtocolA { ... }
   ...
}

然后一切正常并且正确满足协议(protocol)要求。

但是

如果我这样实现:

class Donald: ProtocolX {
   ...
   var handler: ProtocolA & ProtocolB
   ...
}

我有一个编译时问题,报告我的类 Donald 不符合 ProtocolX(根据规范,要求 var handler 必须符合 ProtocolA).

理论上 var handler 符合ProtocolA(但它也符合ProtocolB)。

那么我的问题是:为什么会出现编译时问题?我这边的 Swift 限制或概念问题?

最佳答案

没有充分的理由为什么它不能工作,只是编译器还不支持它。

目前,ProtocolX 指定处理程序必须是 ProtocolA 类型,这意味着如果您使用 ProtocolA 以外的任何内容声明您的类 Donald > 类型的处理程序将不满足协议(protocol)的要求。

但是,您可以将处理程序指定为 ProtocolA 类型,但将其设置为 ProtocolA & ProtocolB 类型的属性。在这种情况下,该属性将被转换为 ProtocolA,您将需要进行额外的转换才能使用 ProtocolB 的属性。例如:

typealias ProtocolAB = ProtocolA & ProtocolB

class AB: ProtocolAB {
    func doSomethingA() {}
    func doSomethingB() {}
}

class Donald: ProtocolX {
    var handler: ProtocolA {
        return AB()
    }

    func f() {
        handler.doSomethingA() // is valid
        handler.doSomethingB() // is not valid without casting the handler as `ProtocolB`
    }
}

关于Swift 4 协议(protocol)组合一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46955159/

相关文章:

ios - Swift - 在 segue 之后保存 ViewController 设置

ios - 在 Swift 4 中移动 UIBezierPath 笔划的最佳方式是什么?

ios - 如何以编程方式更改 UIDatePicker 的选定日期颜色 - Swift 4?

swift - 从构造的名称中获取 Swift 变量的值

ios - 无法使用类型为 '[NSAttributedStringKey : Any]' 的索引下标类型为 'String' 的值

java - iOS : Write ByteArray ( [Int8] ) to a file in swift 4

swift - UIApplicationOpenURLOptionsKey :Any return String:Any

swift - 如何附加到 ["foo": "bar"]

ios - Swift/从 tableView 执行自定义转场

swift - 没有尾随闭包支持具有默认参数值的方法?