Marc
02/21/2021, 6:54 PMsealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
dbaelz
02/21/2021, 7:08 PMResult<out R>
is a typo and it should be Result<out T>
?
A good explanation of this construct and possible usage scenarios could be found in this article.
In my own simple words: Most prominent example might be the typical network response where you either have a success with a payload or an error with a reason. It avoids this (anti) pattern to have response classes with isSuccess
boolean and a payload and error property and one of both is set depending on the success status.Marc
02/21/2021, 8:19 PMdiesieben07
02/21/2021, 8:59 PMResult
has one type parameter called R
. Success
has one type parameter called T
. Success
then extends Result
and sets `Result`'s type parameter to whatever its own T
is. So a Success<String>
is a Result<String>
.
Error
is special, it has no type parameters, and instead every Error
is a Result<Nothing>
.Marc
02/21/2021, 9:08 PMAnimesh Sahu
02/22/2021, 4:21 AMNothing
is top-most type in the type system (subclass of every class) sort of imaginary, and hence no object can satisfy it.
For example:
var a = if(cond) 10 else 10.5
a = "Hello" // error: a must be a Number
the type of a is inferred as Number
, as Int and Double are subclasses of Number.
Similarly, if you do something like this:
var b = null
the inferred type would be closest intersection, in this case is Nothing?
, a nullable Nothing, and hence you cannot assign anything to b.
This is not really a good example where it is used, but you can instead find better examples in 'contravariance' sections with in
modifiers, to understand better.