假设我有两个像这样的pojo:
data class Test (
var id : Long? = null
)
data class TestOther (
var id : Long = 0,
var isCool : Boolean = false
}
然后我有一个像这样的中缀函数:
infix fun <T : Any?> KProperty<T>.equal(rhs : KProperty<T>) = BinaryExpression<Boolean>(this, rhs, EQUALS)
然后这可以按我期望的那样很好地工作:
Test::id equal TestOther::id
但是这样做也是,因为T是所有扩展Any?的类型:
Test::id equal TestOther::isCool
总有一种方法可以指定通用约束,以便可以比较可为空和不能为空的类型,但是不同类型的对象不能不必为每种可能的具体类型都指定重载?
答案 0 :(得分:2)
目前无法执行。您可以关注此问题以获取更多详细信息 JSON API docs
我在这里看到一种解决方法(类似于该问题中的解决方法)。这个想法是将KProperty<R>
包装到包装类中而无差异。如您所见,KProperty
类型具有out R
的方差,在示例中与我们相反。您可以点击链接以获取有关Kotlin中声明方差异的详细信息
https://youtrack.jetbrains.com/issue/KT-13198
解决方法按预期的那样严格
class KWrapper<R>(val p : KProperty<R>)
infix fun <T : KWrapper<R>, R> T.equal(rhs : T) = false
val <T> KProperty<T>.wrap get() = KWrapper(this)
val a = Test::id.wrap equal TestOther::id.wrap //fails: Long vs Long?
val b = Test::id.wrap equal Test::id.wrap //works
val c = Test::id.wrap equal TestOther::isCool.wrap // fails Long vs Boolean
缺点是您需要分别为左右参数使用.wrap
扩展属性(或扩展功能)