Kotlin 紹介 - Null Safety 2020年9月 4日 はじめに 弊社プロダクトの「連絡とれるくん」では、サーバサイドに Kotlin を採用しています。 Kotlin 採用理由の 1 つに Null Safety があります。 採用当初はあった方がよさそうくらいの感覚だったのですが、使い続けてみて null の概念のある静的型付け言語には無くてはならないもの、に変わってます。 そんな Null Safety について開発経験を基に紹介します。 【目次】 ・ Null Safety とは ・ なぜ null を管理したいか ・ 基本は non-null type で ・ Kotlin の Null Safety で気を付けるべきこと ・ 終わりに Null Safety とは 公式ドキュメント にある通りなんですが、簡単に言うと ・ null を代入できる型 nullable type ・ null を代入できない型 non-null type の 2 つに分けて null をうまい具合に管理することです。 なぜ null を管理したいか null とはすべての参照型に代入可能な便利なものです。 初期値やデフォルト値にできます。 ただ、すべての参照型に代入できるということは、制約が無さすぎるのです。 静的型付け言語のメリットの 1 つは、継承関係の無い型 A から型 B への代入をコンパイルエラーで防げること(つまり制約になる)です。 null はこの制約にとらわれないジョーカーのようなものです。 non-null type があると、 null に対して制約を課せます。 関数による例 例えば、参照型の引数を 1 つ持つ関数の実装を考えてみます。 参照型の引数は null の可能性があるため、 null についての振る舞いも設計します。 (もちろん null を考慮しないまま実装して NullPointerException が発生したら、その時はスタックトレースから調査、という方針もありますが・・・) 引数が null の場合の振る舞いとしては大体下記になると思います。 ・ IllegalArgumentException を投げる ・ 何もしないで終わる (戻り値があるなら null を返す) ・ null を何らかのデフォルト値に置換して、処理を行う ここで non-null type の引数にすれば、関数側の null についての振る舞い設計が不要になり、関数本来の機能に集中できます。 基本は non-null type で 関数の引数を non-null type にしても、関数の呼び出し側で null 除外する手間は残ってます。 Kotlin には null 除外のための便利な機能 ?. / ?: がありますが、手間であることには変わりないです。 関数の呼び出し側、つまりコード全体で non-null type を使うようにすれば、null 除外の手間は減ります。 どうしても nullable type を使わなければならない箇所は存在しますが、そこだけ気を付けて null 除外すれば Null Safety なコードになっていきます。 Kotlin の Null Safety で気を付けるべきこと Kotlin on JVM の場合、 Java のライブラリを簡単に使用可能です。 Java のライブラリから取得できる値 (メソッドの戻り値など) は、 nullable type と non-null type 両方の可能性がある platform type というものになります。 ※ ただし 決められた @NotNull / @Nullable アノテーション が付いていれば nullable type と non-null type に明確に分かれます platform type は、 non-null type の可能性があるため null 除外処理が無くてもコンパイルは通りますが、 nullable type の可能性があるため null である可能性は十分にあります。 もやっとする話なんですが、ようは @NotNull / @Nullable アノテーションを明示していない Java ライブラリは、コンパイラによる Null Safety の支援は受けられないので、ライブラリの仕様を理解して使うしかない、ということです。 終わりに Null Safety について感じていることを言語化してみました。 最初に書いたとおりなんですが、 null の概念のある静的型付け言語は nullable type / non-null type の使い分けはできて当たり前、と思うようになってます。 今後、他の言語を採用することになっても、 Null Safety の有無は大きな判断基準の 1 つになると思います。 個人的に好きな言語である C# は 8.0 から Null 許容参照型 が導入されてて嬉しいです。 書いた人: プロダクトデベロップメント部 藤本泰輔