16: Static Constructors ∕ Module Constructors - royal-lang/rl GitHub Wiki

Royal has support for static constructors. Module constructors are also static constructors but at the module level.

To declare a static constructor you use the static keyword before a constructor (this)

Static Struct Constructors

A static constructor is declared using static this. For structs it will be run during thread initialization. Both struct and ref struct supports static constructors.

struct Foo
{
    static this()
    {
        ...
    }
}

Just like static constructors a struct can also have a static destructor which will be called during thread termination.

Destructors are declared using the destroy keyword.

struct Foo
{
    static destroy()
    {
        ...
    }
}

Module Constructors

Module constructors are constructors that are run during initialization of a module either during program initialization or during thread initialization.

Generally you cannot guarantee in what order constructors are called and thus you shouldn't rely on a constructor being called before another.

Constructors can only access data within their own module or data that is guaranteed to be initialized from shared constructors or already has a compile-time known value associated with them.

This means you cannot access any field that is constructed from another module's static constructor.

static this()
{
    ...
}

Since globals are thread-local by default in Royal, unless declared shared then it means values has to be initialized for very thread. This is achieved by running the static constructor for a module every time a new thread is created.

Of course it's not always desirable to run a constructor more than once which is why you can declare it as shared which means it will only run once during program initialization.

shared static this()
{
    ...
}

Just like there are constructors, there are also destructors for modules.

You declare a destructor using destroy.

You cannot allocate memory in a destructor.

static destroy() // Run when the thread terminates
{
    ...
}
shared static destroy() // Run during program exit
{
    ...
}