Ковариантность/Инвариантность

Есть sealed-class Result, который параметризован двумя типами - типом успешного результата (T) и типом ошибки (R).

От него наследуются два класса:

 a. Success<T, R> - data class, принимает в конструктор объект типа T

 b. Error<T, R> - data class, принимает в конструктор объект типа R

Нужно создать функцию, которая возвращает объект типа Result и сделать так, чтобы результат функции можно было присвоить переменным со следующими типами:

Result<Number, String>
Result<Any, String>

И нельзя было присвоить переменным со следующими типами:

Result<Int, CharSequence>
Result<Int, Any>

то есть класс Result должен быть ковариантным по параметру T и инвариантным по параметру R.


Ответы (1 шт):

Автор решения: matua
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     // Нормально компилируется, T ковариантен
    val res3: Result<String, Any> = res1  // не компилируется, R инвариантен (Type Mismatch)
}

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

    retrun if(random) {
        Result.Success("Success Example")
    } else {
        Result.Error(404)
    }
}
→ Ссылка