sealed class 사용
sealed class Result<out T : Any> {
data class Success<out T : Any>(val data: T) : Result<T>()
sealed class Error(val exception: Exception) : Result<Nothing>() {
class RecoverableError(exception: Exception) : Error(exception)
class NonRecoverableError(exception: Exception) :
Error(exception)
}
object InProgress : Result<Nothing>()
}
- sealed class 는 동일한 파일 또는 중첩 클래스로 정의해야 한다.
- sealed class 인 Result 클래스는 private 생성자로 생성된다.
- sealed class 인 Error 클래스는 private 생성자로 접근할 수 없다.
- val r : Result<Int> = Result.Error(Exception("error")) //컴파일 에러 발생
- 컴파일러만이 사용할 수 있는 생성자를 생성한다.
- InProgress 는 저장할 상태가 없기때문에 불필요한 할당을 피하기위해서 싱글톤으로 생성했다.(object)
val result = when(result) {
is Result.Success -> TODO()
is Result.Error.RecoverableError -> TODO()
is Result.Error.NonRecoverableError -> TODO()
is Result.InProgress -> TODO()
}
- when 구문을 사용했을 때 sealed class 하위 클래스를 모두 분기 처리되야한다.
- 하나라도 분기 처리되지 않으면 컴파일 에러가 발생한다.
val <T> T.exhaustive: T get() = this
- 위 확장 프로퍼티를 사용하여 새로운 sealed 하위 클래스 생성시 when 구문에서 리턴없이도 컴파일 에러가 발생되도록 할 수 있다.
when(result) {
is Result.Success -> TODO()
is Result.Error.RecoverableError -> TODO()
is Result.Error.NonRecoverableError -> TODO()
is Result.InProgress -> TODO()
}.exhaustive
- when{ }.exhaustive 처럼 사용 가능
댓글
댓글 쓰기