Optional chaining

Safely read nested instance fields when a link in the chain might be `nil`.

Use ?. instead of . to access an instance field or method. If the value on the left is nil, the whole access short-circuits to nil: no runtime error.

Chains like user?.profile?.address?.city walk each link only while the current value is a non-nil instance. A nil in the middle stops the rest of the chain and yields nil.

Optional chaining is read-only: you cannot assign through ?.. A missing property on a real instance still errors; ?. only guards against nil receivers.

Nested fields

Read through nested instance fields when every link exists.

Nested fields
class Address {
  init(city) { this.city = city; }
}

class Profile {
  init(bio, address) {
    this.bio = bio;
    this.address = address;
  }
}

class User {
  init(name, profile) {
    this.name = name;
    this.profile = profile;
  }
}

var user = User("Rain", Profile("developer", Address("Kathmandu")));

print user?.name;
print user?.profile?.bio;
print user?.profile?.address?.city;
output
Rain
developer
Kathmandu

nil root or middle

`nil` at any point in the chain returns `nil` for the rest.

nil root or middle
class User {
  init(name, profile) {
    this.name = name;
    this.profile = profile;
  }
}

var nobody = nil;
print nobody?.name;

var bob = User("Bob", nil);
print bob?.name;
print bob?.profile?.bio;
print bob?.profile?.address?.city;
output
nil
Bob
nil
nil

In conditions and loops

Optional chaining works anywhere an expression is allowed.

In conditions and loops
class Address {
  init(city) { this.city = city; }
}
class Profile {
  init(address) { this.address = address; }
}
class User {
  init(name, profile) {
    this.name = name;
    this.profile = profile;
  }
}

var users = #[
  User("Alice", Profile(Address("NYC"))),
  User("Bob", nil),
];

for (u von users) {
  var city = u?.profile?.address?.city;
  if (city == nil) {
    print u?.name + " has no city";
  } else {
    print u?.name + " lives in " + city;
  }
}
output
Alice lives in NYC
Bob has no city

Notes