如何在泛型Kotlin类中将上限与空值混合

如何在泛型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

我试图从AbstractList派生一个具有上限可比性的委托类,并希望将列表用作可以包含空值的委托。 以下是我的实现:

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