Reputation: 1709
While playing a little bit with Swift I tried to write a readonly and lazy initialized property. I quickly wrote that line of code just to learn that it's not allowed.
// no valid Swift code.
lazy let foo : Int = { return 42 }()
You have to declare lazy properties as var
.
The swift book clearly states that let with lazy is not possible for a good reason:
“You must always declare a lazy property as a variable (with the var keyword), because its initial value might not be retrieved until after instance initialization completes. Constant properties must always have a value before initialization completes, and therefore cannot be declared as lazy.”
Supposing I would like to have a readonly lazy property in swift. What's the best way to archive that?
Upvotes: 28
Views: 10642
Reputation: 5371
You need to declare the property at initialization time for it to be immutable.
class Class {
let foo: Int
init() {
self.foo = 42
}
}
Upvotes: -1
Reputation: 2071
Its possible to do this with a computed property and a private struct. There is no need for the lazy keyword on the static var value, as assigning it the result of a block is implicitly lazy.
var foo: Int {
struct Holder {
static var value = { return 42 }()
}
return Holder.value
}
Upvotes: 5
Reputation: 41226
You can also use a private backing variable that initializes lazily:
var foo : Int { return _foo }
private lazy var _foo :Int = { return 42 }()
Upvotes: 9
Reputation: 72760
If readonly and private are synonyms for you in this specific case, then you can make the setter private by explicitly declaring it:
private(set) lazy var foo : Int = { return 42 }()
That's a good compromise between immutability and laziness.
Upvotes: 49