kmizuの日記

プログラミングや形式言語に関係のあることを書いたり書かなかったり。

Kotlinのsmart castの限界

Kotlinには所謂smart castと呼ばれる(公式ドキュメントがそう称している)機能があります。

たとえば以下のように、ifの条件式でnullチェックをすることにより、その中ではnot-nullableな型として扱うことができます。

gist.github.com

ただし、一般的に、あるnullableな型がある地点において、「not-nullableである」かどうかを完全かつ健全に判定する方法はおそらく決定不能(コンピュータのプログラムで判定できない問題)です。そのため、Kotlinは実際にはもっと保守的な方法、つまり、完全かつ健全な判定はできないが、not-nullableと判定できた場合にはかならずnot-nullableになっている、ようなアルゴリズムを採用しています。

このため、smart castは自明にある程度の制限があります。たとえば、あるString?な型について、not nullかつnot emptyであることを判定するメソッドnotNullAndNotEmptyがあったとします。このメソッドを使った次のコード

gist.github.com

は意図通りにはたらいてくれません。これは、Kotlinが呼び出し先のメソッドの制御フローまで追跡できないための制限です。現実的に、呼び出し先のメソッドの制御フローまで追跡していたらコンパイル時間が膨大になってしまいますし、この制限自体は妥当だと思います。ただ、smart castといっても、このような制限が存在するといったことは(Kotlinにおける良いメソッドの設計のためにも)理解しておいた方が良いと思います。