如何在 kotlin 中使用带有泛型的密封类`

Mat*_*lfe 2 generics kotlin sealed-class kotlin-sealed

我有以下课程,但我正在努力解决泛型问题


sealed class Result<T,E> {
    data class Success<T>(val data: T): Result<T,Void>()
    data class Failure<E>(val error: E): Result<Void,E>()
}


fun interface SeqListener<T,E> {
    fun onComplete(result: Result<T,E>)
}

abstract class Seq<T,E> {

    var started = false
        private set

    var complete = false
        private set

    private lateinit var seqListener: SeqListener<T,E>

    fun start(listener: SeqListener<T,E>) {
        if (!started) {
            seqListener = listener
            started = true
            return doStart()
        } else throw IllegalStateException("cannot call start on a sequence more than once")
    }

    fun success(result: Result.Success<T>) {
        complete(result)
    }

    fun fail(result: Result.Failure<E>) {
        complete(result)
    }

    private fun complete(result: Result<T,E>) {
        if (!complete) {
            complete = true
            seqListener.onComplete(result)
        } else throw IllegalStateException("cannot call success or fail multiple times")
    }

    abstract fun doStart()
}
Run Code Online (Sandbox Code Playgroud)

但编译器抱怨说,上面的 for failure/success 的调用对于 success 的调用来说complete(result)是错误的类型。Required: Result<T,E> Found: Result.Success<T>

如果我将complete方法更改为:complete(result: Result<*,*>)那么这些错误就会消失,但调用会seqListener.onComplete(result)失败Required: Result<T,E> Found: Result<*,*>

任何帮助,将不胜感激。

Ten*_*r04 6

将您的类型定义为out并用于Nothing未使用的类型。这将使编译器对可接受的向上转换非常宽松。

Nothing类型可以被认为是 的相反Any,因为它在逻辑上被视为所有事物的子类型。因此,对于协变out类型,它可以隐式向上转换为任何类型。

sealed class Result<out T, out E> {
    data class Success<T>(val data: T): Result<T, Nothing>()
    data class Failure<E>(val error: E): Result<Nothing, E>()
}
Run Code Online (Sandbox Code Playgroud)