You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin泛型疑问:为何超类型是DataActor<out Data>?求惯用实现方案

Kotlin泛型场景下的优雅实现方案求助

我构建了一个最小示例来展示问题,目前已有一个不够优雅的解决方案,希望找到更符合Kotlin惯用写法的实现方式。

关键代码行(第29行):val actor: DataActor<out Data> = when ...
添加out修饰后,无法调用接收Data作为参数的方法(比如第36行的add方法)。

我已经理解问题的核心:如果将类型声明为DataActor<Data>,语法上会允许向任意DataActor添加任意Data实例(例如向NumberActor中添加Text对象)。但我的实际场景是仅使用当前DataActor产出的数据作为它的输入,因此这种操作是安全的。

但我还没找到答案:如何用Kotlin的惯用方式实现这个需求?

目前能想到的无需unchecked casts的唯一方案,是把所有操作都放在when语句分支里,但这会在实际业务中导致大量代码重复。

示例代码如下:

interface Data
class Text(var text: String) : Data
class Number(var number: Int) : Data

interface DataActor<A: Data> {
    fun add(element: A): Boolean
    fun get(index: Int): A
}

class TextActor : DataActor<Text> {
    private val list = ArrayList<Text>()
    override fun add(element: Text) = list.add(element)
    override fun get(index: Int): Text = list[index]
}

class NumberActor : DataActor<Number> {
    private val list = ArrayList<Number>()
    override fun add(element: Number) = list.add(element)
    override fun get(index: Int): Number = list[index]
}

enum class Selector {
    Number,
    Text
}

fun main() {
    val selector = Selector.Number

    // 为什么这里的类型是DataActor<out Data>而不是DataActor<Data>?
    val actor = when(selector) {
        Selector.Number -> NumberActor()
        Selector.Text -> TextActor()
    } // as DataActor<Data> // 不够优雅的解决方案

    val data = actor.get(0)
    // 无法调用,因为需要DataActor<in Data>或DataActor<Data>类型
    actor.add(data)
}

内容的提问来源于stack exchange,提问作者Tavaro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 13:13:19