【问题标题】:Why does this Kotlin parameter type with an upper bound need a cast?为什么这个具有上限的 Kotlin 参数类型需要强制转换?
【发布时间】:2019-11-08 12:53:29
【问题描述】:

以下函数采用Serializable 的列表和对列表中的各个元素进行序列化的 lambda。

    val os = BufferOutputStream()
    fun <T : Serializable> writeList(list: List<Serializable>, emitter: (T, BufferOutputStream) -> Unit) {
        os.writeInt(list.size)
        for (v in list) {        // v is of type Serializable
            emitter(v as T, os)  // why do we need to cast V as T? 
        }
    }

T 已经必须实现Serializable 时,为什么我需要将Serializable 类型的v 转换为T&lt;T : Serializable&gt; 不是确定采用 Serializable 的函数/lambda 必须采用 T 吗?

【问题讨论】:

  • &lt;T : Serializable&gt; 是否没有确定采用 Serializable 的函数/lambda 必须采用 T?”确实如此。但是您正试图反过来:将Serializable 传递给采用T 的函数。

标签: generics kotlin


【解决方案1】:

然而你的发射器不需要任何Serializable - 它只需要T。这就是您需要强制转换的原因 - 列表元素的类型为 Serializable。如果您将其更改为:

val os = BufferOutputStream()
    fun <T : Serializable> writeList(list: List<T>, emitter: (T, BufferOutputStream) -> Unit) {
        os.writeInt(list.size)
        for (v in list) {
            emitter(v, os)
        }
    }

它不需要强制转换。

【讨论】:

    【解决方案2】:

    我想发布一个示例,说明为什么它不应该在没有强制转换的情况下编译。

    假设有两个类Class1Class2 实现或扩展Serializable。如果您使用包含Class1 的列表调用此函数,但发射器采用Class2,那么当从列表中取出Class1 并将其传递给仅采用Class2 的发射器时,这将是一个类转换异常.

    在@r2rek 发布的示例中,该函数强制列表和发射器为相同的类。

    【讨论】:

      猜你喜欢
      • 2020-01-27
      • 1970-01-01
      • 2021-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多