Kotlinでnot-null assertion operator (!!)の混入を防ぎたい

Kotlinには、not-null assertion operatorという、nullableな値を、非null型に強制で変換してくれる演算子(!!)があります。nullな値に付けると、Null Pointer Exceptionを投げてくれます。

詳しい説明は、kotlinlang.org にお願いするとして、出だしは以下の文言から始まっています。

The third option is for NPE-lovers
(ここでいう、NPEとはNull Pointer Exceptionのことです)

NPE-loversって・・・😇

当然アプリをクラッシュさせる挙動は防ぎたいので、 !!を使う場合は、Null Pointer Exceptionをcatchするか、以下のようにif文でのnullチェックや エルビス演算子(?.)などを使って、クラッシュを回避するはずです。

// nullableStringがnullの時は、Null Pointer Exceptionをthrowする
println(nullableString!!)

// nullableStringがnullでない時のみ実行する(if文でのnullチェックを行うパターン)
if (nullableString != null) { println(nullableString) }

// nullableStringがnullでない時のみ実行する(エルビス演算子を使うパターン)
nullableString?.let { println(nullableString) }

個人でのサービスやOSSならともかく、仕事などで多人数で開発する場合は、Null Pointer Exceptionをcatchするのは実装忘れの可能性もあるため、基本的にはif文でのnullチェックや エルビス演算子を使うように制限したいところです。この辺は、いちいちレビューで指摘したくないので、コーディング規約として定義している会社さんも多いのではないでしょうか。

ちなみに、TypeScriptやSwiftでは、not-null assertion operator に該当するものをlinterで防いでくれます。
TypeScriptのLinter
SwiftのLinter

じゃあ、KotlinのLinterもと思って、ktlintのissueを漁ってみたところ、closeされてるんですよね。それが、こちらです。

軽くcloseされた理由を見ると、以下の通りです。

In fact, by banning only !! you may inadvertently push people to ?. which is entirely the wrong thing which you should fail over to.
(訳: !!を禁止にすると、 本来 !! で書いてフェールオーバーにすべき箇所を、 ?. で書いて、誤った実装にしてしまうかもしれません。)
Someone missing them is not a function of the operators being bad, it's an education issue.
(訳: 誰かが誤って !! の演算子を使っているのであれば、それは演算子の問題ではなく教育の問題です。)

ということで、ktlintは、 not-null assertion operator や、 force cast (as)をチェックする気はないみたいですね。

ktlintで明確に否定されてる以上、どうしてもこれらの演算子を防ぐためには、別のlinterを作るか、dangerを使うしかないようですね😔

とりあえずdangerで作って、いずれ防ぎたい内容が増えてきたら、別のlinterを作るかもしれません。

この記事が気に入ったらサポートをしてみませんか?