【问题标题】:Cannot override with a stored property in Swift不能用 Swift 中的存储属性覆盖
【发布时间】:2018-04-03 22:43:19
【问题描述】:

在 Swift 4.1 中覆盖惰性变量的正确方法是什么? 以下代码在 swift 4.0 中运行良好,但从 swift 4.1 开始,我在覆盖时收到警告,所以我猜它在 swift 5 中将不可用

我曾经:

class A {

    lazy var myVar: String = {
        return "A"
    }()
}

class B: A {

    override lazy var myVar: String = { // WARNING Cannot override with a stored property myVar
        return "B"
    }()
}

我想这有点像这样,但它并不性感..

class A {

    lazy var myVar: String = {
        return createMyVar()
    }()

    func createMyVar() -> String {
        return "A"
    }
}

class B: A {

    override func createMyVar() -> String {
        return "B"
    }
}

【问题讨论】:

  • 似乎工作得很好,在Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2) Target: x86_64-apple-macosx10.9
  • @Alexander 这个问题是关于 Swift 4.1 的。它适用于 4.0,但显然不是 4.1(我还没有 Xcode 9.3,所以我无法检查)。
  • “它适用于 4.0,但显然不适用于 4.1”这是问题应该提到的。我的印象是 Swift 主要版本(如 2 或 3 和 4)之间的差异,而不是次要版本 4.0 和 4.1 之间
  • ?自 Swift 3 以来,此错误一直存在。
  • @ArnaudDorgans 我也有同样的问题。而且我真的很想使用子类化。如果您想出一些优雅的解决方案,请告诉我。 Hamish 解决方案可能是我们需要做的,但我宁愿不介绍那些额外的代码行...

标签: swift overriding


【解决方案1】:

虽然没有技术上的理由说明你不能用引入存储的属性来覆盖一个属性(尽管它会在观察者覆盖时引起歧义;请参阅this Q&A for more info),但 Swift 目前不允许你这样做。

事实上,在 4.0 中,您可以使用 lazy 属性 was unintended 覆盖属性(因为覆盖引入了存储),因此您将在 4.1 中收到警告,在 Swift 5 模式中收到错误,以便保持源代码兼容性(在#13304 中实现)。

不过,您可以使用转发计算属性获得相同的结果:

class A {
  lazy var myVar: String = "A"
}

class B : A {

  // Note that this isn't a particulary compelling case for using 'lazy', as
  // the initialiser expression is not expensive.
  private lazy var _myVar: String = "B"

  override var myVar: String {
    get { return _myVar }
    set { _myVar = newValue }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多