🚧 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.