首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin:即使类有一个可以为空的泛型参数类型E,赋值也会失败

问Kotlin:即使类有一个可以为空的泛型参数类型E,赋值也会失败
EN

Stack Overflow用户
提问于 2020-04-01 22:23:13
回答 2查看 151关注 0票数 0

我正在努力处理可空类型和非可空类型。有两个错误。我定义了一个实现“队列”概念的类,如下所示,试图使其泛型参数类型可为空,这里有第一个错误:

代码语言:javascript
复制
class QueueLightweight<T: Any?> { //: Queue<T?> removed because of Java clashes, but it's another question
        protected var size = 0
        protected var first: NodeQLW<T>? = null
        protected var last: NodeQLW<T>? = null

        protected class NodeQLW<E>(var item: E) {
            var next: NodeQLW<E>? = null
        }

        ....

        fun iterator(): Iterator<T> {
            return IteratorQLW(this)
        }

        ....

        fun add(e: T?): Boolean {
            val n: NodeQLW<T>
            n = NodeQLW(e) // <--- first error: 
            // "type inference failed: required: QueueLightweight.NodeQLW<T> , found: QueueLightweight.NodeQLW<T?> "
            if (size == 0) {
                last = n
                first = last
                size = 1
            } else {
                last!!.next = n
                last = n
                size++
            }
            return true
        }
    }

然后,我定义了一个Iterator子类,如下所示,在突出显示的行(通过箭头)中,出现了错误。

代码语言:javascript
复制
protected class IteratorQLW<E: Any?>(var q: QueueLightweight<E>) :
Iterator<E> {
var n: NodeQLW<E>?
init {
    n = q.first
}

override fun hasNext(): Boolean {
    return n != null
}

override fun next(): E {
    var e: E
    e = null // <--- error here: null cannot be a value of a non-null type E
    if (n != null) {
        e = n!!.item
        n = n!!.next
    }
    return e
}

}

我不知道如何修复这些错误。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-01 22:45:38

默认情况下,该类型允许为<T: Any?>,因此您的类类型定义可以只是<T>,而不是nullable。在使用类时(例如使用QueueLightweight<String>而不是QueueLightweight<String?>),可以将泛型类型指定为不可为空的类型,因此在使用类中的泛型类型时,必须将其视为不可为空的类型。

这是你的第一个问题的根源。NodeQLE的构造函数可能需要一个不可为空的参数,但您强制它为null.Your add方法应采用T参数,而不是强制的T?。

然后在迭代器中将一个变量声明为(可能)不可为空的E,但将其赋值为null。您需要将变量设置为可空。由于即使E不可为空,它也可以返回null,因此如果没有next值,则必须抛出异常。但这可以通过更改分支来简化,因此该方法应如下所示:

代码语言:javascript
复制
override fun next(): E {
    n?.let {
        n = it.next
        return it.item
    }
    throw NoSuchElementException()
}
票数 2
EN

Stack Overflow用户

发布于 2020-04-02 02:53:58

不可为空的类型是相应的可为空的类型的子类型。例如,任何String都是一个String?,因此String是String?的一个子类型。因此,任何类型,包括不可为空的类型,都是Any?的子类型,E: Any?绑定不会强制E为可空(并且可以移除)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60973150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档