如何在泛型Kotlin类中将上限与空值混合
我试图从AbstractList派生一个具有上限可比性的委托类,并希望将列表用作可以包含空值的委托。 以下是我的实现:如何在泛型Kotlin类中将上限与空值混合,kotlin,generics,nullable,Kotlin,Generics,Nullable,我试图从AbstractList派生一个具有上限可比性的委托类,并希望将列表用作可以包含空值的委托。 以下是我的实现: package org.baier.test class MyList<out T: Comparable<@kotlin.UnsafeVariance T>>(private val delegate: List<T>) : AbstractList<T>() { override val size = delega
package org.baier.test
class MyList<out T: Comparable<@kotlin.UnsafeVariance T>>(private val delegate: List<T>) : AbstractList<T>() {
override val size = delegate.size
override fun get(index: Int): T {
return delegate[index]
}
}
fun main() {
val delegate1: List<Int> = listOf(1, 2, 3, 4, 5)
val list1 = MyList(delegate1)
val delegate2: List<Int?> = listOf(1, 2, 3, null, 4, 5)
val list2 = MyList(delegate2)
}
package org.baier.test
类MyList(私有val委托:List):AbstractList(){
覆盖值大小=delegate.size
覆盖乐趣获取(索引:Int):T{
返回委托[索引]
}
}
主要内容(){
val delegate1:List=listOf(1,2,3,4,5)
val list1=MyList(delegate1)
val delegate2:List=listOf(1,2,3,null,4,5)
val list2=MyList(delegate2)
}
在main方法中,我尝试用List和List实例化Mylist类。
为什么后一个会出现编译器错误
“类型不匹配。必需:找到可比较的:Int?”
为什么是Int?不属于可比类型?
Int
被定义为可比类型。Int?
是可比的?
但不是可比的?
,因为Int
没有具体实现可比的
这至少有几个原因:
null是否应被视为大于或小于任何特定整数值是不明确的
实际上,您不能使用可为null的变量作为可比较的排序对象,因为您不能在null
上调用compareTo()
。例如(null为Int?)。compareTo(1)
将返回null
,而不是-1/0/1,因此您实际上无法使用它对某些内容进行排序Comparable.compareTo()
的约定是,它在两个方向上的工作方式相同,因此使用空值是不可能的。您可以定义自己的Comparable,它使用可空值,这可能有一些用途,但不用于使用标准库排序函数对列表进行排序
如果不使用此类进行排序,则可能需要定义其他上限。它不起作用的原因是Tenfour04已经提出的
无论如何,如果您想让它也能与null一起工作,您可以尝试说您的列表是List
类型,然后为get
覆盖定义某种默认值,当它恰好为null时。例如:
class MyList<out T: Comparable<@kotlin.UnsafeVariance T>(private val delegate: List<T?>, private val nullValuesProvider: (Int) -> T) : AbstractList<T>() {
override val size = delegate.size
override fun get(index: Int): T {
return delegate[index] ?: nullValuesProvide(index)
}
}
class MyList T):AbstractList(){
覆盖值大小=delegate.size
覆盖乐趣获取(索引:Int):T{
返回委托[索引]?:nullValuesProvide(索引)
}
}
或者,也可以选择空值的默认值:
class MyList<out T: Comparable<@kotlin.UnsafeVariance T>(private val delegate: List<T?>, private val defaultIfNull: T) : AbstractList<T>() {
override val size = delegate.size
override fun get(index: Int): T {
return delegate[index] ?: defaultIfNull
}
}
类MyList