generics - Kotlin 中的方差/协方差泛型

标签 generics kotlin covariance invariance

有一个密封类 Result,它有两种类型参数化 - 成功结果 (T) 和错误类型 (R)。

它被两个类继承:

a.成功 - 数据类,在构造函数中接受对象 T

b.错误 - 数据类,在构造函数中接受对象 R

我需要创建一个返回 Result 对象的函数。该函数必须以以下方式创建:

  • 该函数的结果可以分配给以下类型的变量:
    Result<Number, String>
    Result<Any, String>
  • 该函数的结果不能分配给以下类型的变量:
    Result<Int, CharSequence>
    Result<Int, Any>

即类 Result 必须在 T 参数上协变,在 R 参数上不变。

最佳答案

您可以使用declaration-site variance由 Kotlin 在 Result 类的声明中提供。

  • T -> 默认情况下 T 是不变的
  • out T -> 使 T 协变
  • 在 T 中 -> 使 T 保持不变

示例:

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)
}

函数可以将结果返回为:

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

    retrun if(random) {
        Result.Success("Success Example")
    } else {
        Result.Error(404)
    }
}

关于generics - Kotlin 中的方差/协方差泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62227806/

相关文章:

android - Kotlin Map 项目列表流

android - 无法在改造的错误主体中获得错误响应

kotlin - kotlin:列出任何对象的属性-方差错误

c# - 是否可以使用 JSON.Net 将 JSON 反序列化为 List<MyObject<T,K>>

c# - 当 T 正在实现类时,C++/CLI 中的 IComparable<T>

Java 枚举和泛型

kotlin - 直接在委托(delegate)中设置和获取属性

Java泛型在集合及其子类型中扩展和 super 实现

generics - 需要澄清关于 `Box` 、 `Vec` 和其他集合的(协)方差的 Rust Nomicon 部分

wpf - 一般行为