NullishOperators - friendlyhj/ZenUtils GitHub Wiki
@since 1.23.0
Nullish Operators provide some shorthands of if (isNull(a))
, including Nullish Coalescing Operator (??
), Nullish coalescing assignment (?=
) and Optional chaining (?.
). These can not handle primitive types (int, double, etc.), since they can not be null.
The nullish coalescing (??
) operator is a logical operator that returns its right-hand side expression when its left-hand side expression is null, and otherwise returns its left-hand side expression.
It is equivalent to the code below, although no local variable generated actually.
// getA() ?? getB();
val a = getA();
isNull(a) ? getB() : a;
The nullish coalescing assignment (?=
) operator, also known as the logical nullish assignment operator, only evaluates the right expression and assigns to the left if the left operand is null.
It is equivalent to the code below.
// a ?= b;
if (isNull(a)) {
a = b;
}
Its scope of application is consistent with the other operand assignments.
var a as string;
// ok
a += "foo";
a ?= "foo";
zenClass Foo {
var bar as string;
zenConstructor(bar as string) {
this.bar = bar;
}
}
var foo as Foo;
// ok
foo.bar += "baz"
foo.bar ?= "baz"
// error: invalid lvalue
val map as string[string] = {};
map["foo"] ~= "bar";
map["foo"] ?= "bar";
Other operand assignments return the modified value for local variables, but nullish coalescing assignment always returns nothing.
var a as int = 4;
// prints 2
print(a -= 2);
// error: void has no default value
var b as string = null;
print(b ?= "bar");
The optional chaining (?.
) operator accesses an object's property or calls a function. If the object accessed or function called using this operator is null, the expression short circuits and returns null instead of throwing an exception.
It is equivalent to the code below.
// getA()?.callFunction();
val a = getA();
isNull(a) ? null : a.callFunction();
If the return type of the member is primitive, optional chaining operator will return a nullable wrapper of the return value. You can use nullish coalescing operator to unwrap it.
val data as IData = {};
// error: NullPointerException, because data.foo is null
data.foo.asInt();
// returns null
data.foo?.asInt();
// returns 100
data.foo?.asInt() ?? 100;