generics - Kotlin:即使类具有可为空的泛型参数类型 E,赋值也会失败
问题描述
我正在为可空和不可空类型苦苦挣扎。有两个错误。我定义了一个实现“队列”概念的类,如下所示,试图使其通用参数类型为空,这里有第一个错误:
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 子类,如下所示,在突出显示的行中(通过箭头),有错误。
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
}
}
我不明白如何解决这些错误。
解决方案
默认情况下,该类型允许为空,因此您的类类型定义可以只是<T>
,而不是<T: Any?>
。泛型类型可以在使用类时指定为不可为空(例如使用QueueLightweight<String>
而不是QueueLightweight<String?>
),因此当您在类中使用泛型类型时,您必须将其视为不可为空。
这是您的第一个问题的根源。您的 NodeQLE 期望其构造函数有一个可能不可为空的参数,但您强制它为 null。您的add
方法应该采用T
参数,而不是强制的T?
。
然后在您的迭代器中,您将一个变量声明为(可能) non-nullable E
,但为其分配一个 null 。您需要使变量可以为空。由于即使 E 不可为空,它也可以返回 null,因此如果没有下一个值,则必须抛出异常。但这可以通过改变分支来简化,所以方法应该是这样的:
override fun next(): E {
n?.let {
n = it.next
return it.item
}
throw NoSuchElementException()
}
推荐阅读
- java - java.lang.ClassCastException: 类 [我无法转换为类 java.lang.Comparable
- python - Seaborn情节,传说重叠图
- python - fasttext' 在 Windows 10 上没有属性 'train_supervised'
- excel - 如果用户过滤数据,如何在 Excel 中使用 SUMIF?
- swiftui - 如何在 SwiftUI 中使用按钮呈现菜单(不是上下文菜单)?
- vulkan - Vulkan 队列系列说明
- python - 选择时验证码崩溃。硒蟒
- python - 如何使用 Xpath 提取带有 css 的文本字段
- reactjs - 为什么我无法读取未定义的属性“内部”并且无法实例化 firebase-analytics.js - 请务必先加载 firebase-app.js
- django - django widget_tweaks 可以将输入渲染为 textarea 框吗?