用返回非可选值的计算属性重写返回 Optional 值的计算属性



以下内容在运行 Swift 4 的 Xcode 9.2 上编译和运行没有问题:

class ParentWithComputedOptional {
    var computedOptional: Int? { return nil }
}
class ChildThatUnwraps: ParentWithComputedOptional {
    override var computedOptional: Int { return 10 }
}

请注意,在父级中,computedOptionalInt?,但在子项中,它被覆盖为Int。此外,必须指定 override 关键字才能编译代码。这在操场和适当的项目上都进行了测试。

这是预期行为吗?如果是,Apple 文档中是否有适用于此方案的相关页面?

这种特殊的覆盖情况似乎没有记录在官方语言指南的任何地方,但在 Swift 的 4.0 版本更新日志中提到了(寻找 SR-1529(。


本主题需要一些其他信息:

实际上,此行为不仅限于可选,也适用于其他协变类型,只要重写的属性是派生类中的计算只读属性即可。例如,以下代码也将在 Swift 4.1 中进行编译。

class Animal {}
class Koala: Animal {}
class Foo {
  var x: Animal { return Animal() }
}
class Bar: Foo {
  override var x: Koala { return Koala() }
}

这是一个不违反 Liskov 替换原则的边缘情况,因为 Base 类的属性是只读计算的。因此,如果Bar的实例保存在类型为 Foo 的变量中,则无法改变其 x 属性,以便在将对象向下转换为 Bar 类型的变量时创建类型错误。

最新更新