繁体   English   中英

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

[英]How to use sealed classes with generics in kotlin`

我有以下课程,但我正在努力解决 generics


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

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

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

任何帮助,将不胜感激。

将您的类型定义为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>()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM