目的
- Sealed Classの定義と状態管理を紹介した
- https://qiita.com/alingogo/items/cd5ee4bc917c9064bf8a
- 特にjavaと違う使い方を説明した
- 本文はSealed Classのその他の使い方を紹介する
内容
例外処理の苦労点
- kotlin言語には、チェック済み例外がない
- ドキュメントにに明文化されず、発生しても誰にも気付かれない恐れがある
sealed classで解決できる
- 例外を投げることを代わりに、違う結果インストールを返す(例:success, error...)
- もし処理結果ケースが足りない場合は、コンパイラーは自動的に何か結果ケースが足りないことを通知できる
- 結果ケースが同じファイルに定義されるので、読みやすくになる
- javaぽいexceptionの定義
exceptionでの処理方法
fun requestWeatherIcon(id: String): WeatherIcon = try {
API.getWeatherIcon(id)!!
} catch (ex: IOException) {
throw IconClientException(
message = "Io request failed",
cause = ex
)
} catch (ex: RestClientException) {
throw IconClientException(
message = "Server request failed. Id: $id.",
cause = ex
)
}
class IconClientException(message: String, cause: Exception? = null) : RuntimeException(message, cause)
sealedで結果ケースを定義
sealed class IconResult {
data class Success(val icon: WeatherIcon) : IconResult()
data class Error(val message: String, val cause: Exception? = null) : IconResult()
}
sealedで処理
fun requestWeatherIcon(id: String): IconResult = try {
val iconProfile = API.getWeatherIcon(id)
IconResult.Success(icon = iconProfile)
} catch (ex: IOException) {
IconResult.Error(
message = "Server request failed. Id: $id.",
cause = ex
)
} catch (ex: RestClientException) {
IconResult.Error(
message = "Server request failed. Id: $id.",
cause = ex
)
}
val icon = when (val result = requestWeatherIcon("3")) {
is IconResult.Success -> result.icon
is IconResult.Error -> "http://domain.com/defaulIcon.png"
}
足りない場合はcompile error
val icon = when (val result = requestWeatherIcon("3")) {
is IconResult.Success -> result.icon
}
'when' expression must be exhaustive, add necessary 'is Error' branch or 'else' branch instead