onSuccess, onFailure, fold로 성공과 실패(exception이 발생한 경우)를 따로 처리가 가능합니다.
또는 getOrXXX로 exception이 발생하지 않고 잘 수행된 경우 원하는 결괏값을, 아닌 경우는 XXX 에 해당되는 동작을 하게 됩니다.
fruitResult.onSuccess {
// 성공 시 받은 결괏값에 대한 처리
}.onFailure {
// 실패 시 발생한 throwable을 처리
}
fruitResult.fold({
// 성공 시 받은 결괏값에 대한 처리
}, {
// 실패 시 발생한 throwable을 처리
})
var fruitName: String? = null
// 실패 시 default 값을 반환
fruitName = fruitResult.getOrDefault("")
// 실패 시 else block의 결괏값을 반환
fruitName = fruitResult.getOrElse {
when(it) {
is IllegalStateException -> "Sold out"
is NullPointerException -> "null"
else -> throw it
}
}
// 실패시 throwable이 다시 throw 됩니다.
fruitName = fruitResult.getOrThrow()
또한 map과 recover를 이용해 성공과 실패 시 원하는 값으로 바꿀 수 있습니다.
둘 다 xxxCatching 을 제공하는데 map과 recover시 발생할 수 있는 exception 으로부터 안전하기 위해 runCatching으로 감싸저 있습니다.
Result로 반환하므로 chaining 하여 이용 가능합니다.
또한 getOrElse 대신 아래와 같이 recover를 이용해 볼 수도 있습니다.
fruitResult.map {
it.toUpperCase()
}
fruitResult.recover {
when(it) {
is IllegalStateException -> "Sold out"
is NullPointerException -> "null"
else -> throw it
}
}
위에 얘기한 내용을 엮어보면 아래와 같은 방법으로 써볼 수 있습니다.
(map 경우는 큰 의미는 없지만 예제목적으로 mapCatching 을 사용하였습니다.)
val fruitName = runCatching {
getRandomFruit()
}.mapCatching {
it.toUpperCase()
}.recoverCatching {
when(it) {
is IllegalStateException -> "Sold out"
is NullPointerException -> "null"
else -> throw it
}
}.getOrDefault("")
이 경우는 성공한 경우만 uppercase가 동작합니다 recover를 map보다 먼저 해주면 recover된 값 또한 map에서 변환될 수 있으니 작성 시 의도에 맞게 순서를 잘 정할 필요가 있습니다.
그 외 기타 사항
Result는 return 하려고 하면 ‘kotlin.Result’ cannot be used as a return type 이라는 에러가 발생합니다.
사용하고 싶은경우 다음의 stackoverflow 글에서 gradle 설정법에 대하여 설명 되어 있습니다.
다만 위의 stackoverflow 답변에 있는 내용 대로 왜 막아두었는지 여기와 여기에 잘 설명되어 있습니다.