Result (sealed class)
はじめに
sealed class
をついさっき初めて知ったのですが、さらに
Kotlin標準ライブラリのResult
を活用したエラーハンドリング ... も知らず...
今回(自分のために)記事にしました。
Result
とは?
Result
は Kotlin 標準ライブラリで提供される型で、成功と失敗を安全に扱うための仕組みです。非同期処理やエラーハンドリングを簡潔かつ型安全に記述できるため、多くの場面で活用できます。
Result
の特徴
-
成功 (
Success
) と 失敗 (Failure
) を1つの型で表現できる。 - 型安全であり、例外を安全にカプセル化できる。
- Kotlin 1.3 以降で利用可能。
- 主に関数の戻り値として使用される。
基本的な使い方
成功と失敗を返す関数
Result.success
と Result.failure
を使って、関数の戻り値を明確に表現します。
fun divide(a: Int, b: Int): Result<Int> {
return if (b != 0) {
Result.success(a / b)
} else {
Result.failure(IllegalArgumentException("Divider can't be zero"))
}
}
呼び出し例
成功と失敗を簡単に処理できます。
val result = divide(4, 2)
result.fold(
onSuccess = { println("Result: $it") },
onFailure = { println("Error: ${it.message}") }
)
主なメソッド
fold
1. 成功時と失敗時の処理をそれぞれ指定できます。
result.fold(
onSuccess = { println("Success: $it") },
onFailure = { println("Failure: ${it.message}") }
)
getOrNull
2. 成功時は値を返し、失敗時は null
を返します。
val value = result.getOrNull()
println(value) // 成功: 結果を表示。失敗: null。
exceptionOrNull
3. 失敗時の例外を取得できます。
val exception = result.exceptionOrNull()
println(exception?.message) // 成功: null。失敗: 例外のメッセージ。
map
4. 成功時の値を変換します。
val mappedResult = result.map { it * 2 }
println(mappedResult.getOrNull()) // 成功: 値を変換後に表示。失敗: null。
mapCatching
5. 変換中に例外が発生する可能性がある場合に使用します。
val safeMappedResult = result.mapCatching { it / 0 }
safeMappedResult.fold(
onSuccess = { println("Result: $it") },
onFailure = { println("Error: ${it.message}") }
)
実用例
1. 簡単なエラーハンドリング
Result
を使って、例外を明確に処理できます。
fun fetchDataFromServer(): Result<String> {
return try {
Result.success("Data fetched successfully")
} catch (e: Exception) {
Result.failure(e)
}
}
val result = fetchDataFromServer()
result.fold(
onSuccess = { println(it) },
onFailure = { println("Error: ${it.message}") }
)
2. リトライ処理
複数回の試行で成功を得る例です。
fun retryableOperation(): Result<Int> {
return try {
val value = (1..10).random()
if (value > 5) Result.success(value) else throw RuntimeException("Value too low")
} catch (e: Exception) {
Result.failure(e)
}
}
val retryResult = (1..3).asSequence()
.map { retryableOperation() }
.first { it.isSuccess }
println(retryResult.getOrNull())
Result
を使うメリット
コードの簡潔化:
成功と失敗のハンドリングを1つの型で表現できるため、複雑なエラーチェックが不要。
まとめ
Kotlin 標準ライブラリの Result
を使うことで、成功と失敗を安全かつ簡潔に扱うことができます。
例外処理や非同期コードでその真価を発揮するらしい(今回未確認)ので、どんどん使って知見を深めたいです。
この便利な Result
を使って、よりメンテナブルなコードを書けるように頑張ります。
参考URL
-
Kotlin - Result
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result/ -
Kotlinの標準APIを知る【Result編】
https://zenn.dev/p_guma/articles/fc7c07d0420dd1 -
Kotlin: Resultの簡単なまとめ
https://satoshun.github.io/2018/12/result/
Discussion