简体   繁体   English

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

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

I have the following classes but I'm struggling with generics我有以下课程,但我正在努力解决 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()
}

but the compiler complains that the calls to: complete(result) for fail/success above are of the wrong type Required: Result<T,E> Found: Result.Success<T> for the one from success.但是编译器抱怨说,上面对失败/成功的complete(result)的调用是错误的类型Required: Result<T,E> Found: Result.Success<T>来自成功的调用。

If I change the complete method to: complete(result: Result<*,*>) then those errors go away but the call to seqListener.onComplete(result) fails with Required: Result<T,E> Found: Result<*,*>如果我将complete方法更改为: complete(result: Result<*,*>)那么这些错误 go 消失,但对seqListener.onComplete(result)的调用失败并出现Required: Result<T,E> Found: Result<*,*>

Any help would be appreciated.任何帮助,将不胜感激。

Define your types as out and use Nothing for the unused ones.将您的类型定义为out并为未使用的类型使用Nothing This will make the compiler very lenient about acceptable upcasting.这将使编译器对可接受的向上转换非常宽容。

The Nothing type can be thought of as the opposite of Any , because it is logically treated as a subtype of everything. Nothing类型可以被认为是Any的对立面,因为它在逻辑上被视为一切的子类型。 So with covariant out types, it can be implicitly upcast to anything.因此,使用协变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