无法使用Swift中的存储属性覆盖

Arn*_*ans 11 overriding swift

在Swift 4.1中覆盖lazy var的正确方法是什么?以下代码在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"
    }()
}
Run Code Online (Sandbox Code Playgroud)

我想这是这样的,但它不性感..

class A {

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

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

class B: A {

    override func createMyVar() -> String {
        return "B"
    }
}
Run Code Online (Sandbox Code Playgroud)

Ham*_*ish 14

虽然没有技术上的理由说明为什么你不能用引入存储的属性覆盖属性(虽然它可能会引起观察者覆盖的歧义; 有关更多信息,请参阅此问答),Swift目前不允许这样做.

事实上在4.0中你可以用属性覆盖lazy属性是无意的(因为覆盖引入了存储),因此你将在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 }
  }
}
Run Code Online (Sandbox Code Playgroud)