【Kotlin】contractを試す

車の暖房が壊れて、数日間凍えながら出社していました。kiyokawaです。

Kotlin1.3から追加された「contract」を試してみました。

KotlinのStringにはisNullOrEmpty()という値がnullでも空文字でもないということを確認できる便利な関数があります。(正確には、CharSequenceの拡張関数)
しかし、Kotlin1.3より前はisNullOrEmpty()ではスマートキャストが効かず、ifの中でもNullableなStringとして扱わなければなりませんでした。

ですが、Kotlin1.3で導入されたcontractという機能のおかげでisNullOrEmpty()でもスマートキャストが効くようになりました。
関数の定義を見てみると以下のようになっています。

関数の先頭に出てきましたね、contract。
contractは関数を呼び出したあとの状況を関数が保証するという機能です。
今回の関数のcontractを説明すると

となります。
以上を踏まえて、お試しにAnyがString型かどうかを確認するcontractを作ってみます。

今回はお試しで作ってみたものなので、実際にAnyがStringかどうか確認するときは普通に

みたいな感じでやってしまうとは思います。
実はこのお試しの例を作る前にEitherという成功(Right)、失敗(Left)を表すクラスにisRight()を作ってifの中では成功時の結果を取得できるように作ってみたんですが、contractではジェネリクスを使うことは出来ないようだったので断念しました。

まとめ

・contractを使いコンパイラに状況を保証することでスマートキャストが効くようになる
・contractはExperimentalなので、実際に使うときは注意してください
・Experimentalが外れるまではcontractを使った関数と、利用側には必ず@ExperimentalContractsを付ける必要があります
・Kotlin1.3からisNullOrEmpty()でスマートキャストが効くようになった理由が分かって良かったです