Synthetic Composite Type Fieldstled

🚧 Status: Synthetic fields are not implemented yet.

Fields which are not stored in the composite value are synthetic, i.e., the field value is computed. Synthetic can be either read-only, or readable and writable.

Synthetic fields are declared using the synthetic keyword.

Synthetic fields are read-only when only a getter is provided.

struct Rectangle {
    pub var width: Int
    pub var height: Int

    // Declare a synthetic field named `area`,
    // which computes the area based on the `width` and `height` fields.
    //
    pub synthetic area: Int {
        get {
            return width * height
        }
    }

    // Declare an initializer which accepts width and height.
    // As `area` is synthetic and there is only a getter provided for it,
    // the `area` field cannot be assigned a value.
    //
    init(width: Int, height: Int) {
        self.width = width
        self.height = height
    }
}

Synthetic fields are readable and writable when both a getter and a setter is declared.

// Declare a struct named `GoalTracker` which stores a number
// of target goals, a number of completed goals,
// and has a synthetic field to provide the left number of goals.
//
// NOTE: the tracker only implements some functionality to demonstrate
// synthetic fields, it is incomplete (e.g. assignments to `goal` are not handled properly).
//
pub struct GoalTracker {

    pub var goal: Int
    pub var completed: Int

    // Declare a synthetic field which is both readable and writable.
    //
    // When the field is read from (in the getter), the number
    // of left goals is computed from the target number of goals
    // and the completed number of goals.
    //
    // When the field is written to (in the setter), the number
    // of completed goals is updated, based on the number
    // of target goals and the new remaining number of goals.
    //
    pub synthetic left: Int {
        get {
            return self.goal - self.completed
        }

        set(newLeft) {
            self.completed = self.goal - newLeft
        }
    }

    init(goal: Int, completed: Int) {
        self.goal = goal
        self.completed = completed
    }
}

let tracker = GoalTracker(goal: 10, completed: 0)
// `tracker.goal` is `10`
// `tracker.completed` is `0`
// `tracker.left` is `10`

tracker.completed = 1
// `tracker.left` is `9`

tracker.left = 8
// `tracker.completed` is `2`

It is invalid to declare a synthetic field with only a setter.

Last updated