Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot override with a stored property in Swift

What is the right way to override lazy var in Swift 4.1? The following code work fine in swift 4.0 but since swift 4.1 I have warning on override, so I guess it'll be unavailable in swift 5

I used to:

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"
    }()
}

I guess this is something like this but its not sexy..

class A {

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

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

class B: A {

    override func createMyVar() -> String {
        return "B"
    }
}
like image 754
Arnaud Dorgans Avatar asked Apr 03 '18 22:04

Arnaud Dorgans


1 Answers

Although there's no technical reason why you cannot override a property with one that introduces storage (although it can raise ambiguities with observer overrides; see this Q&A for more info), Swift doesn't currently allow you to do so.

The fact that in 4.0 you could override a property with a lazy property was unintended (as the override introduces storage), and so you'll get a warning in 4.1 and an error in Swift 5 mode in order to preserve source compatibility (implemented in #13304).

You can however achieve the same result with a forwarding computed property though:

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 }
  }
}
like image 124
Hamish Avatar answered Oct 23 '22 16:10

Hamish