可空属性对象的Kotlin中缀运算符

时间:2018-08-09 17:33:23

标签: kotlin

当我有这样的kotlin课时:

class Test (
    val param1 : Long,
    val param2 : Long
)

class EqualityExpr<T: Any> (
    val lhs : KProperty<T>,
    val rhs : KProperty<T>
)

infix fun <T: Any> KProperty<T>.equals(KProperty<T> rhs) : EqualityExpr<T> {
    return EqualityExpr(this, rhs)
}

表达式Test::param1 equals Test::param2可以正常工作并调用infix函数。但是,当我这样做时:

class Test (
    val param1 : Long?,
    val param2 : Long?
)

同一表达式失败。如果不是KProperty<*>的子类,这些可为空的属性的类型是什么?

1 个答案:

答案 0 :(得分:1)

该调用不适用于可为null的属性,因为您期望rhs参数与扩展名的接收者具有相同的T类型参数,但实际上并没有。其中一个是KProperty<Long>,而另一个是KProperty<Long?>,并且由于{null不能为空,Long?不能为T推断Any }上限。

val kProperty1: KProperty<Long> = Test::param1
val kProperty2: KProperty<Long?> = Test::param2

一种可行的方法是让T类型的参数为空,如果它对您有用:

class EqualityExpr<T : Any?> (
        val lhs: KProperty<T>,
        val rhs: KProperty<T>
)

infix fun <T : Any?> KProperty<T>.equals(rhs: KProperty<T>): EqualityExpr<T> {
    return EqualityExpr(this, rhs)
}

进行此更改后,kProperty1 equals kProperty2调用才有意义,因为将Long?推断为type参数,并且两个属性的类型均为KProperty<Long?>