Skip to content

Optionals

This content is not available in your language yet.

As it was mentioned in type system overview, all primitive types, Structs and Messages could be nullable. That is, they don’t necessarily hold any value, aside from null — a special value, which represents the intentional absence of any other value.

Variables or fields of Structs and Messages that can hold null are called “optionals”. They’re useful to reduce state size when the variable isn’t necessarily used.

You can make any variable or a field an optional by adding a question mark (?) after its type declaration. The only exceptions are map<K, V> and bounced<Msg>, where you can’t make them, inner key/value type (in case of a map) or the inner Message (in case of a bounced) optional.

Optional variables or optional fields that are not defined hold the null value by default. You cannot access them without checking for null first. But if you’re certain they are not null at a given moment, use the non-null assertion operator !! to access their value.

Trying to access the value of an optional variable or an optional field without using !! or without checking for null beforehand will result in a compilation error if the compiler can track it, and if not — in an exception with exit code 128: Null reference exception.

Example of optionals:

struct StOpt {
opt: Int?; // Int or null
}
message MsOpt {
opt: StOpt?; // Notice, how the struct StOpt is used in this definition
}
contract Optionals {
opt: Int?;
address: Address?;
init(opt: Int?) { // optionals as parameters
self.opt = opt;
self.address = null; // explicit null value
}
receive(msg: MsOpt) {
let opt: Int? = 12; // defining a new variable
if (self.opt != null) { // explicit check
self.opt = opt!!; // using !! as we know that opt value isn't null
}
}
}