Composite Type Fields

Fields are declared like variables and constants. However, the initial values for fields are set in the initializer, not in the field declaration. All fields must be initialized in the initializer, exactly once.

Having to provide initial values in the initializer might seem restrictive, but this ensures that all fields are always initialized in one location, the initializer, and the initialization order is clear.

The initialization of all fields is checked statically and it is invalid to not initialize all fields in the initializer. Also, it is statically checked that a field is definitely initialized before it is used.

The initializer's main purpose is to initialize fields, though it may also contain other code. Just like a function, it may declare parameters and may contain arbitrary code. However, it has no return type, i.e., it is always Void.

The initializer is declared using the init keyword.

The initializer always follows any fields.

There are three kinds of fields:

  • Constant fields are also stored in the composite value, but after they have been initialized with a value they cannot have new values assigned to them afterwards. A constant field must be initialized exactly once.

    Constant fields are declared using the let keyword.

  • Variable fields are stored in the composite value and can have new values assigned to them.

    Variable fields are declared using the var keyword.

  • Synthetic fields are not stored in the composite value, i.e. they are derived/computed from other values. They can have new values assigned to them.

    Synthetic fields are declared using the synthetic keyword.

    Synthetic fields must have a getter and a setter. Getters and setters are explained in the next section. Synthetic fields are explained in a separate section.

In initializers, the special constant self refers to the composite value that is to be initialized.

Field types must be storable. Non-storable types are:

  • Functions

  • Accounts (AuthAccount / PublicAccount)

  • Transactions

Fields can be read (if they are constant or variable) and set (if they are variable), using the access syntax: the composite value is followed by a dot (.) and the name of the field.

// Declare a structure named `Token`, which has a constant field
// named `id` and a variable field named `balance`.
//
// Both fields are initialized through the initializer.
//
// The public access modifier `pub` is used in this example to allow
// the fields to be read in outer scopes. Fields can also be declared
// private so they cannot be accessed in outer scopes.
// Access control will be explained in a later section.
//
pub struct Token {
    pub let id: Int
    pub var balance: Int

    init(id: Int, balance: Int) {
        self.id = id
        self.balance = balance
    }
}

Note that it is invalid to provide the initial value for a field in the field declaration.

pub struct StructureWithConstantField {
    // Invalid: It is invalid to provide an initial value in the field declaration.
    // The field must be initialized by setting the initial value in the initializer.
    //
    pub let id: Int = 1
}

The field access syntax must be used to access fields – fields are not available as variables.

pub struct Token {
    pub let id: Int

    init(initialID: Int) {
        // Invalid: There is no variable with the name `id` available.
        // The field `id` must be initialized by setting `self.id`.
        //
        id = initialID
    }
}

The initializer is not automatically derived from the fields, it must be explicitly declared.

pub struct Token {
    pub let id: Int

    // Invalid: Missing initializer initializing field `id`.
}

A composite value can be created by calling the constructor and providing the field values as arguments.

The value's fields can be accessed on the object after it is created.

let token = Token(id: 42, balance: 1_000_00)

token.id  // is `42`
token.balance  // is `1_000_000`

token.balance = 1
// `token.balance` is `1`

// Invalid: assignment to constant field
//
token.id = 23

Last updated