Reputation: 2384
Static properties in swift are initialised lazily. I wanted to use a static property of a class as a dependency that I could easily replace while doing a unit test. The value of the property was immediately invoked closure, but I expected this closure to never execute if I replace the property without ever reading it.
However upon setting the static property, the original closure gets executed. It's not the case for lazy instance properties. Why is that?
To illustrate the issue, I have provided a sample code.
The output of this code:
class Foo {
static var bar1: String = {
print("here we are")
return "This is static bar"
}()
lazy var bar2: String = {
print("here we are too")
return "This is instance bar"
}()
}
let foo = Foo()
print("We have a Foo instance")
Foo.bar1 = "Overwritten bar 1"
print(Foo.bar1)
foo.bar2 = "Overwritten bar 2"
print(foo.bar2)
is:
We have a Foo instance
here we are
Overwritten bar 1
Overwritten bar 2
Upvotes: 2
Views: 784
Reputation: 535576
However upon setting the static property, the original closure gets executed. It's not the case for lazy instance properties. Why is that?
What answer would satisfy you? Are you asking for someone to read Apple's mind? You're as capable of reading the Swift source code as anyone else, so go read it and see what it does. Personally, I agree with your expectation. In my opinion this behavior is a bug, and I've filed a bug report with Apple. If you agree, file one too. But I wouldn't expect anything to change if I were you. And regardless, your question can appeal only to opinion, which is not a good fit for Stack Overflow.
In case you're curious, my bug report is number 19085421, and reads, in part:
Summary: A lazy var's initializer should not be evaluated at all if the var is written to without being read first. But that is what a global var does.
Steps to Reproduce: Run the enclosed project.
Expected Results: I am assigning to the global var before anyone ever reads its value. Therefore I expect that its initializer will never be evaluated.
Actual Results: Its initializer is evaluated, as the logging in the console proves. This defeats, to some extent, the purpose of laziness.
Upvotes: 1