我正在尝试用niceAssign()替换Assign()方法:
class Builder<T : Any>(val kClass: KClass<T>) {
fun <K> assign(prop: KProperty1<T, K>, value: K): Builder<T> = TODO("doing other stuff here")
fun <K> niceAssign(call: KClass<T>.() -> Pair<KProperty1<T, K>, K>) : Builder<T> {
val (prop, value) = call(kClass)
return assign(prop, value)
}
}
val builder = Builder(Data::class)
builder.assign(Data::someProperty, "some value") // (1)
builder.niceAssign { ::someProperty to "some value" } // (2)
由于生成器对象是使用Data类生成的,因此我真的不需要在传递属性引用时显式指示Data类。 Assign方法已经知道该属性属于哪个类。所以我不想每次在assign方法中都写“ Data ::”(就像代码(1)一样),但是我想将“ Data ::”作为niceAssign参数的接收者属性传递,所以我可以引用::来自“此”对象的someProperty。
此代码段不起作用,因为我将KClass作为接收者传递,并且KClass没有T的属性引用。 那么,有什么方法可以使它工作?
答案 0 :(得分:1)
如果要将属性引用传递给高阶函数,则它应该是一个T
作为接收器的函数。
在上述情况下,必须为:
fun <K> niceAssign(call: T.() -> Pair<KProperty0<K>, K>) : Builder<T> {
...
}
但是要“解压”传递给niceAssign
参数(以便可以将其进一步传递给assign
函数),则需要T
的实例,例如:
val (prop, value) = call(kClass.createInstance())
由于assign
参数类型不匹配,因此结果也无法照原样传递给prop
方法,因此此方法将需要一些额外的代码重做。