I often see the following Code A about sealed class in Kotlin.
1: By the structure of the sealed class Result,it seems that Nothing just like the subclass of R, right?
2: I think Code A should be Code B, is it right?
3: And more, it seems that I never see the code just like Code C, is it wrong?
Code A
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
Code B
sealed class Result<out R> {
data class Success<out R>(val data: R) : Result<R>()
data class Error(val exception: Exception) : Result<Nothing>()
}
Code C
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Fail<out K>(val data: K) : Result<K>()
}
Added Content
To Joffrey: Thanks!
In Code 1 , Noting is just look like the subclass of R
I think Code 2 is easy to understand more then Code 1, right?
Code 1
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
val cityDetails: Result<ExploreModel>
get() {
val destination = destinationsRepository.getDestination(cityName)
return if (destination != null) {
Result.Success(destination)
} else {
Result.Error(IllegalArgumentException("City doesn't exist"))
}
}
if (cityDetails is Result.Success<ExploreModel>) {
...
} else {
onErrorLoading()
}
Code 2
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
val destination = destinationsRepository.getDestination(cityName)
val cityDetails= if (destination != null) Result.Success(destination) else Result.Error(IllegalArgumentException("City doesn't exist"))
if (cityDetails is Result.Success<ExploreModel>) {
...
} else {
onErrorLoading()
}
Add content again:
By the declaration of the class Result, out R and out T can be different type, and out R and out T can be any type.
Why is Code 3 correct, and Code 4 wrong?
Does it mean that T must be the subclass of R in sealed class Result?
BTW, Code 5 can be compiled.
Code 3
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
val cityDetails: Result<ExploreModel>
get() {
val destination = destinationsRepository.getDestination(cityName)
return if (destination != null) {
Result.Success<ExploreModel>(destination)
} else {
Result.Error(IllegalArgumentException("City doesn't exist"))
}
}
if (cityDetails is Result.Success<ExploreModel>) {
...
} else {
onErrorLoading()
}
Code 4
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
val cityDetails: Result<String> //It's String type
get() {
val destination = destinationsRepository.getDestination(cityName)
return if (destination != null) {
Result.Success<ExploreModel>(destination)
} else {
Result.Error(IllegalArgumentException("City doesn't exist"))
}
}
if (cityDetails is Result.Success<ExploreModel>) {
...
} else {
onErrorLoading()
}
Code 5
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Fail<out K>(val data: K) : Result<K>()
}
val aa: Result1<Any>
get(){
return if (true) Result1.Success("Hello") else Result1.Fail(3)
}
Add content thirdly:
To Joffrey: Thank you very much!
Your answer is great, I can understand completely, thanks again
Anyway, I think the Code Ok is better than the Code 1, it's clear without any ambiguous, right?
Code OK
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
val cityDetails: Result<Any>
get() {
val destination = destinationsRepository.getDestination(cityName)
return if (destination != null) {
Result.Success(destination)
} else {
Result.Error(IllegalArgumentException("City doesn't exist"))
}
}
if (cityDetails is Result.Success<ExploreModel>) {
...
} else {
onErrorLoading()
}