当我有这样的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<*>
的子类,这些可为空的属性的类型是什么?
答案 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?>
。