用 returns 非可选值覆盖 属性 一个可选值 returns 一个可选值

Overriding a computed property that returns an Optional value with one that returns a non-Optional

以下在我的 Xcode 9.2 运行 Swift 4:

上编译和运行没有问题
class ParentWithComputedOptional {
    var computedOptional: Int? { return nil }
}

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

请注意,在父项中,computedOptional 是一个 Int?,但在子项中它被覆盖为 Int。此外,必须为要编译的代码指定 override 关键字。这已经在 Playground 和一个合适的项目上进行了测试。

这是预期的行为吗?如果是,Apple 的文档中是否有针对这种情况的相关页面?

这种重写的特殊情况似乎没有在官方语言指南中的任何地方记录,但在 Swift 的 changelog 4.0 版本中有所提及(查找 SR-1529 ).


这个主题需要一些额外的信息:

实际上,这种行为不仅限于可选类型,也适用于其他 covariant 类型,只要被覆盖的 属性 是派生 class。 例如,以下代码也可以在 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 substitution principle 的边缘情况,因为基础 class' 属性 是只读计算的。因此,如果 Bar 的一个实例被保存在类型 Foo 的变量中,就没有办法改变它的 x 属性 以便它将对象向下转换为 Bar.

类型的变量时会产生类型错误