The built-in lazy
lets me do something like:
lazy var myLazy: String = {
print("initializing...")
return "my string"
}()
and the closure won't be evaluated until myLazy
is first evaluated. In other words, "initializing..." won't print until myLazy
is accessed for the first time.
But this doesn't seem to work for propertyWrapper
s. Given the Lazy
wrapper from SE-0258:
@propertyWrapper
enum Lazy<Value> {
case uninitialized(() -> Value)
case initialized(Value)
init(wrappedValue: @autoclosure @escaping () -> Value) {
self = .uninitialized(wrappedValue)
}
var wrappedValue: Value {
mutating get {
switch self {
case .uninitialized(let initializer):
let value = initializer()
self = .initialized(value)
return value
case .initialized(let value):
return value
}
}
set {
self = .initialized(newValue)
}
}
}
I'd expect something like the following to behave like the lazy
example above:
@Lazy var myLazy: String = {
print("initializing...")
return "my string"
}()
But it doesn't. The closure is evaluated immediately printing "initializing..." even if myLazy
is never used.
Note that this isn't how @autoclosure
usually works. Usually if we give it a called closure like this, it will wrap it for later evaluation. In fact, this works as expected:
@Lazy(wrappedValue: {
print("initializing")
return "my string"
}()) var myLazy: String
Like the lazy
example, above, this doesn't evaluate the closure (or print "initializing") until myLazy
is accessed the first time.
Please circle one?
- I'm doing it wrong
- It's a bug
- It's intended behavior