2

There is a sealed-class Result, which is parameterized with two types - success result (T) and error type (R).

It is inheritered by two classes:

a. Success - data class, accepts object T in the constructor

b. Error - data class, accepts object R in the constructor

I need to create a function, which returns Result object. The function has to be created in a way:

  • that the result of this function can be assigned to the variables of the following types:
    Result<Number, String>
    Result<Any, String>
  • that the result of this function can NOT be assigned to the variables of the following types:
    Result<Int, CharSequence>
    Result<Int, Any>

That is class Result must be covariant on T parameter and invariant on R parameter.

matua
  • 597
  • 4
  • 12

1 Answers1

2

You can use the declaration-site variance provided by Kotlin in the declaration of your Result class.

  • T -> By default T is invariant
  • out T -> makes T covariant
  • in T -> makes T contavariant

Example:

sealed class Result<out T, R>(val left: T? = null, val right: R? = null) {
    class Success<T, R>(data: T) : Result<T, R>(left = data)
    class Error<T, R>(data: R) : Result<T, R>(right = data)
}

fun main() {
    val res1 = Result.Success<String, Int>("Test")
    val res2: Result<Any, Int> = res1     // compiles successfully, T is covariant
    val res3: Result<String, Any> = res1  // doesn't compile, R is invariant (Type Mismatch)
}

A function can return Result as:

fun returnResult(): Result<String, Int> {
    val random = Random.nextBoolean() // random, for demonstration

    retrun if(random) {
        Result.Success("Success Example")
    } else {
        Result.Error(404)
    }
}
Animesh Sahu
  • 7,445
  • 2
  • 21
  • 49