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

Swift protocol conformance requirements for subtypes

(如果有人可以建议更好的标题,请提供)

以下代码未编译并出现错误 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()
}

我的看法-ObservedObjectSubclassObservedObject,所以object属性保证是根据协议要求键入 ObservedObject

(同样如此,如果使用协议一致性而不是子类化 - 下面)

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

class ObservedObject: ObservedObjectProtocol {}

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

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

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

您可以通过为您的 Observer 协议创建一个 associatedType 来修复第二个错误,该协议继承自 ObserverObject 然后您可以将 object 定义为相同的类型作为您的关联类型。然后你可以让你的 ObserverClass 有一个 属性 object 类型 ObservedObjectSubclass.

class ObservedObject {}
class ObservedObjectSubclass: ObservedObject {}

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

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