子类型的 Swift 协议(protocol)一致性要求

标签 swift protocols standards-compliance subtype

(如果有人可以建议更好的标题,请这样做)

以下代码无法编译并出现错误 Type 'ObserverClass' does not conform to protocol 'Observer' ,编译器建议通过声明 var object: ObservedObject 进行修复.

class ObservedObject {}
class ObservedObjectSubclass: ObservedObject {}

protocol Observer {
    var object: ObservedObject { get }
}

class ObserverClass: Observer { // Type 'ObserverClass' does not conform to protocol 'Observer'

    // suggested:
    // var object: ObservedObject

    var object: ObservedObjectSubclass = ObservedObjectSubclass()
}

我的看法 - ObservedObjectSubclass ObservedObject ,等等object属性保证为 ObservedObject 类型按照协议(protocol)的要求。

(如果使用协议(protocol)一致性而不是子类化,情况也是如此 - 如下)

protocol ObservedObjectProtocol {}
protocol Observer {
    var object: ObservedObjectProtocol { get }
}

class ObservedObject: ObservedObjectProtocol {}

class ObserverClass: Observer { // same error
    var object: ObservedObject = ObservedObject()
}

为什么编译器不高兴?是当前的限制,还是编译器实际上是正确的并且存在一些逻辑约束?

最佳答案

当您在协议(protocol)中定义变量并为其分配类型时,这将是一个具体类型,因此在符合协议(protocol)时您无法将其更改为该类型的子类。一致性类中声明的变量类型必须与协议(protocol)中声明的类型相同,不能是协变(继承相关)类型。

您可以通过为您的 Observer 协议(protocol)创建一个 linkedType 来修复第二个错误,该协议(protocol)继承自 ObserverObject 然后您可以定义 object 与您的关联类型具有相同的类型。然后,您可以使您的 ObserverClass 具有 ObservedObjectSubclass 类型的属性 object

class ObservedObject {}
class ObservedObjectSubclass: ObservedObject {}

protocol Observer {
    associatedtype ObjectSubclass: ObservedObject
    var object:ObjectSubclass { get }
}

class ObserverClass: Observer {
    var object = ObservedObjectSubclass()
}

关于子类型的 Swift 协议(protocol)一致性要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55918812/

相关文章:

c++ - 这是标准的 C++ 代码吗?

ios - Alamofire4 迁移,Apple Mach-O Linker (id) 错误

ios - 如何在签证结帐中使用文本字段数据作为货币金额

ios - 实现 swift equatable 协议(protocol)给我错误的访问错误。为什么?

swift - 我可以创建一个符合内部协议(protocol)的 iOS 框架,并在我的项目中定义相同的协议(protocol)吗?

swift - 声明一个具有属性返回值 CollectionType<Int> 的 Swift 协议(protocol)?

swift - 将 xib 文件添加到 Swift 包

swift - 使用函数中的内容更改变量值

c++ - 一份拷贝如何使用 memcpy union 简单成员?

c++ - 何时在空实例上调用成员函数会导致未定义的行为?