I just noticed that static
members of Swift structs
are implicitly lazy
.
For instance, this will only call the init
once:
class Baz {
init(){
print("initializing a Baz")
}
}
struct Foo {
static let bar = Baz()
}
var z = Foo.bar
z = Foo.bar
What's the rationale behind this?
What if I want the opposite behaviour?
The static
property defines a "type property", one that is instantiated once and only once. As you note, this happens lazily, as statics behave like globals. And as The Swift Programming Language: Properties says:
Global constants and variables are always computed lazily, in a similar manner to Lazy Stored Properties. Unlike lazy stored properties, global constants and variables do not need to be marked with the
lazy
modifier.
This implicitly lazy behavior is because, as the Swift Blog: Files and Initialization says:
it allows custom initializers, startup time in Swift scales cleanly with no global initializers to slow it down, and the order of execution is completely predictable.
They consciously designed it that way to avoid unnecessarily delaying the startup of the app.
If you want to instantiate the static
property at some particular point in your app (rather than deferring it to where it's first used), simply reference this static
property at that earlier point and the object will be initialized at that time. Given the efforts we put into reducing the latency in starting our apps, you generally wouldn't to want this synchronously during the initial launch of the app, but you can do it wherever you want.