Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
子类型的Swift协议一致性要求_Swift_Protocols_Standards Compliance_Subtype - Fatal编程技术网

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

子类型的Swift协议一致性要求,swift,protocols,standards-compliance,subtype,Swift,Protocols,Standards Compliance,Subtype,(如果有人能推荐一个更好的标题,请推荐) 以下代码编译时未出现错误类型“observeClass”不符合协议“Observer”,编译器建议通过声明var object:ObservedObject进行修复 class ObservedObject {} class ObservedObjectSubclass: ObservedObject {} protocol Observer { var object: ObservedObject { get } } class Obser

(如果有人能推荐一个更好的标题,请推荐)

以下代码编译时未出现错误
类型“observeClass”不符合协议“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()
}
在我看来-
ObservedObject子类
ObservedObject
,因此
对象
属性保证为协议所要求的
ObservedObject
类型

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


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

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

您可以通过为您的
Observer
协议创建
associatedType
来修复第二个错误,该协议继承自
Observer对象
,然后您可以将
对象
定义为与关联类型相同的类型。然后您可以使您的
observer类
具有类型为
ObservedObjectSubclass
的属性
对象

class ObservedObject {}
class ObservedObjectSubclass: ObservedObject {}

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

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

“将对象定义为观察者协议内的计算属性”协议不要求计算/存储;这可能是第二点:“具体类型”是否意味着不能用子类替换?在我看来,这也是继承的主要观点之一。另外,我的问题是,是否存在任何逻辑约束,即为什么编译器不允许子类。@user1244109对,我在考虑协议扩展,所以我关于计算属性的观点不正确,你是对的。至于我的第二种类型,是的,正如我在回答中所显示的,如果您希望能够使用继承的类,那么您需要使用关联的类型。这种情况是这样的,因为在定义协议时,符合协议的每个类都必须以完全相同的方式复制变量和函数声明(除非通过引入associatedtype要求使它们成为泛型)。只需考虑尝试对类执行同样的操作。如果从另一个类继承函数,则不能更改函数签名以使其中一个输入参数成为同一函数的父类实现中输入参数的子类。继承允许您使用子类代替其父类(例如class
ObserverClass:Observer{var object:ObservedObject=ObservedObjectSubclass()}
将符合原始的
Observer
协议,因为变量的类型将与protocol sub中的类型相同。想象一下
让Observer:Observer=ObserverClass()
后跟
Observer.object=differentitoservedobjectsubclass()
的情况。这就是为什么它必须完全符合协议的原因。
class ObservedObject {}
class ObservedObjectSubclass: ObservedObject {}

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

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