代码之家  ›  专栏  ›  技术社区  ›  user1244109

子类型的Swift协议一致性要求[副本]

  •  3
  • user1244109  · 技术社区  · 7 年前

    (如果有人能提出更好的标题,请提出来)

    以下代码编译时没有出现错误 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 属性保证为类型 观察对象 按照协议要求。

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

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

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

    1 回复  |  直到 7 年前
        1
  •  6
  •   Dávid Pásztor    7 年前

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

    您可以通过创建 associatedType 为您的 Observer 协议,继承自 ObserverObject 然后您可以定义 object 与关联类型的类型相同。然后你可以 ObserverClass 拥有财产 对象 类型 ObservedObjectSubclass .

    class ObservedObject {}
    class ObservedObjectSubclass: ObservedObject {}
    
    protocol Observer {
        associatedtype ObjectSubclass: ObservedObject
        var object:ObjectSubclass { get }
    }
    
    class ObserverClass: Observer {
        var object = ObservedObjectSubclass()
    }