Implicitly lazy static members in Swift

cfischer picture cfischer · Jan 8, 2016 · Viewed 21.7k times · Source

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?

Answer

Rob picture Rob · Jan 8, 2016

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.