20. nil conditional operator
This time I will explain LuneScript's nil conditional operator.
Map access
For example, if you have the following Map data,
// @lnsFront: ok
let json = {
"lv1": {
"lv2": {
"lv3": {
"lv4": {
"lv5": {
"val": 1
}
}
}
}
}
};
To access the val of lv5 you have to do something like this:
// @lnsFront: skip
if! let lv1 = json.lv1 {
if! let lv2 = lv1.lv2 {
if! let lv3 = lv2.lv3 {
if! let lv4 = lv3.lv4 {
if! let lv5 = lv4.lv5 {
print( lv5.val );
}
}
}
}
}
Or you have to unwrap it like this:
// @lnsFront: skip
print( (unwrap (unwrap (unwrap (unwrap (unwrap json.lv1).lv2).lv3).lv4).lv5).val );
Either way, it's not good.
The nil conditional operator can be used to easily perform such nested nil checks.
nil conditional operator
Accessing the val of lv5 above using the nil conditional operator looks like this:
// @lnsFront: skip
print( json.lv1$.lv2$.lv3$.lv4$.lv5$.val );
It's pretty refreshing.
The nil-conditional operator, when placed immediately after a nilable expression, controls whether or not the nilable expression is nil or not.
If the nilable expression evaluates to non-nil, the subsequent expression is executed, and if the nilable expression evaluates to nil, the subsequent expression is not executed and the result of that expression is nil.
$[
is used to access the list, and $(
is used to call the function.
For example:
// @lnsFront: ok
class Test {
pub let val:List<int>;
pub fn func():int {
return 100;
}
}
fn sub( test:Test! ) {
print( test$.val$[1], test$.func$() );
}
sub( new Test( [ 1, 2 ] ) ); // 1 100
sub( nil ); // nil nil
In the above example, the sub()
function accesses the Test class val list and func using the nil conditional operator. This allows access without unwrap.
Note
Using a nil conditional access always evaluates to nilable.
For example:
// @lnsFront: ok
class Test {
pub let val:int;
}
fn sub( test:Test! ) {
if! test$.val {
print( _exp + 1 );
}
}
sub( new Test( 10 ) ); // 11
In the above case, the val of the Test class is an int.
In the sub function in the above example, test$.val
is used to access the nilable type Test class instance. At this time, the evaluation result of test$.val
is int! instead of int.
summary
Nil conditional access makes it easy to do deeply nested unwraps.
Next time, we'll talk about module management.