TypeScript と Kotlin での ?.
演算子の違いについて。
TypeScript(optional chaining 演算子)
?.
演算子の左項が nullish(null
もしくは undefined
)であれば
そのチェインにおいてそれ以降の評価を行わずに
チェイン全体の結果として undefined
を返す。
a?.b.c
において a
が nullish だった場合
b
も c
も評価されず undefined
が返る。
const list = ["Qiita", null]; // : (string | null)[]
list[0].substring(1).substring(1); // コンパイルエラー!
list[0]?.substring(1).substring(1); // ★OK
list[0]?.substring(1)?.substring(1); // OK だが冗長
console.log(
list[0]?.substring(1).substring(1)
); // > ita
console.log(
list[1]?.substring(1).substring(1)
); // > undefined
Kotlin(safe call 演算子)
?.
演算子の左項が null
であれば
右項の評価を行わずに
その演算の結果として null
を返し、
チェインを継続する。
a?.b.c
において a
が null
だった場合
b
は評価されず null.c
を評価した結果が返る。
val list = listOf("Qiita", null) // : List<String?>
list[0].substring(1).substring(1) // コンパイルエラー!
list[0]?.substring(1).substring(1) // ★コンパイルエラー!
list[0]?.substring(1)?.substring(1) // OK
println(
list[0]?.substring(1)?.substring(1)
) // > ita
println(
list[1]?.substring(1)?.substring(1)
) // > null
考察:違いの理由
TypeScript では nullish な値に対して .
演算を行うと必ずエラーである。
そのためチェインの途中で nullish な値が出てきた場合
チェインを続ける意味がない。
しかし Kotlin では nullable な型をレシーバーとした拡張関数・拡張プロパティ1を定義できるため
null
に対して .
演算を行える場合がある。
そのためチェインの途中で null
になっても
チェインを続ける意味がある。
/以上
-
例えば
Any?.toString()
関数 ↩