概要
Kotlin2.0からスマートキャストが向上したことにより、いくつか変更されたので紹介します。
変更されたこと
ifスコープ外で評価した結果を使用したスマートキャスト
Sample.kt
sealed interface State {
data object Loading : State
data class Success(val result: String) : State
data class Failed(val throwable: Throwable): State
}
fun printResult(state: State) {
val isSuccess = state is State.Success
if (isSuccess) {
print(state.result)
}
}
fun main() {
val state = State.Success("Hello World!!")
printResult(state)
}
例えば、上記のようなコードがあった場合
2.0以前
if
条件内でならスマートキャストされるが、条件外で評価した値を使用してもキャストはされませんでした。
そのため、 isSuccess
の値を if
の条件判定で使用しても、 state
は Any
として扱われ、 result
プロパティにアクセスできません。
2.0以降
if
条件外で評価した値でもスマートキャストできるようになりました。
そのため、isSuccess
の値をifで条件判定しても、 state
は State.Success
として扱われ、 result
プロパティにアクセスできます。
論理和演算子による型チェックを使用したスマートキャスト
Sample.kt
sealed interface State {
sealed interface HasResult : State {
val result: String
}
data object Initializing : State
data class Loading(override val result: String) : State, HasResult
data class Success(override val result: String) : State, HasResult
data class Failed(override val result: String, val throwable: Throwable): State, HasResult
}
fun printResult(state: State) {
if (state is State.Success || state is State.Failed) {
print(state.result)
}
}
fun main() {
val state = State.Success("Hello World!!")
printResult(state)
}
2.0以前
論理和演算子で条件判定をしても、Any型として扱われます。
そのため、 result
プロパティにアクセスできません。
2.0以降
論理和演算子で条件判定を行うと、最も近い共通のスーパータイプへスマートキャストされます。
そのため今回の例では、 HasResult
へスマートキャストされ、 result
にアクセスすることができます。
まとめ
このようにスマートキャストが便利になっています。
他にも、向上しているものはいくつかあるため、公式サイトを確認するといいかもしれません。