Optional types
In SPL, an optional type is used when a variable or attribute might have no data value
associated with it because the value is unavailable or unknown. When there is no data value for a
variable or attribute, and an optional type is used, the value of that variable or attribute can be
set to null
.
Optional types are composite types, along with tuple and collection types, and are parameterized as such using the underlying type. The underlying type is the type of the data value when the variable or attribute has an associated data value.
Use the form optional<T>
to declare variables or attributes in SPL
that can have either a null
value or a value of the underlying type
T
. For example, you can declare an optional int32
integer in a
stream, list, or tuple, as follows:
stream<int32 i, optional<int32> j> Src = MySource() {}
mutable list<optional<int32>> myList;
type T = tuple<int32 i, optional<int32> j>;
A null
value has a literal representation for every type that can express
a literal value. The characters null
represent a null value.
t
and initializes the
j
attribute to
null
:tuple<int32 i, optional<int32> j> t = { 1, null };
The following example declares and initializes a mutable integer variable to
null
:
mutable option<int32> i = null;
You can
assign a null
value to an optional variable or attribute that has had a
non-null value:mutable optional<int32> i = 5;
i = null;
null
value to a variable or attribute that is of a
non-optional type, you will get a compiler error, or a runtime exception.null
value
assigned. For example: if (var == null) { }
Default initialization
When an operator returns a tuple that is default initialized, for example, a Beacon operator
without an output clause, tuple attributes are initialized with their default values. The default
value for an attribute of optional type is null
.
Value assignment
optional<int32> i = 42;
or
optional<int32> j = i;
The unwrap operator is used to access the non-null value of an optional type for the purposes of assignment to a non-optional type. For example:
int32 k = j!;
The unwrap operator will cause a runtime error
if the value of j is null
.
The unwrap-or-else
operator is used to assign from an optional type to a non-optional type when the value of the
optional type might be null
.
null
, k is assigned the default
value of 4
:int32 k = j ?: 4;
Automatic promotions
T
to optional<T>
.
There are two cases where values are automatically promoted from T
to
optional<T>
:- Literal null
null
is automatically promoted tooptional<T>
if the typeT
can be determined. For example:optional<int32> i = null;
In this case the type can be determined, and the literal null is promoted to type
optional<int32>
.- Expression with optional and non-optional types
- Another case for promotion is when an optional type and a non-optional type appear in an
expression. For example:
In this case the literaloptional<int32> i = 5;
5
, which is of typeint32
, is automatically promoted tooptional<int32>
. Another example:
In this case,if (i == 5) { } // i is of type optional<int32>
5
is promoted to the typeoptional<int32>
.
optional<T>
to
T
.null
: stream<optional<int32> i, optional<int32> j> A = myOp() {
param
p1: null;
p2: (optional<int32>) null;
}
..
composite myOp(output Out) {
param
expression<optional<int32>> $p1;
expression $p2;
graph
stream<Types> Out = Custom() {
logic onProcess:
submit({i=$p1, j=$p2},Out);
}
}
Operators for optional types
- isPresent
- The isPresent operator, (
??
) checks if a variable or attribute of optional type is non-null. The isPresent operator returnstrue
if the variable or attribute of optional type is non-null andfalse
if the variable or attribute isnull
. For example:if (var??) { }
- uwrap
- The unwrap operator (
!
) accesses the data value of an optional type when the value of the optional type is notnull
. For example:
When the value of the optional type isoptional<int32> x = someFunctionThatReturnsAnOptional(); int32 y = x!;
null
, you will get a runtime exception. - unwrapOrElse
- The unwrapOrElse (
?:
) operator gets the data value of an optional type if the value is notnull
. For example:int32 i = optional_var ?: 0;.
The value after the
?:
acts as a default data value that is used when the value of the optional type isnull
.
You can use these operators with expressions of non-optional type. The isPresent operator returns true for non-optional type expressions. The unwwrap operator returns the expression provided for non-optional type expressions. The unwrapOrElse operator returns the expression provided when given a non-optional type expression and never uses the default value.