Kotlin反射:如何通过反射将KFunction添加到列表中?
我想根据类型在运行时添加到Kotlin反射:如何通过反射将KFunction添加到列表中?,kotlin,reflection,Kotlin,Reflection,我想根据类型在运行时添加到MutableListUint>。我基本上得到了它,但我不知道如何将实例信息输入到我拥有的k函数中 这段代码有点做作,但它是我试图做的一个简单的例子。我试图通过在运行时连接分派来摆脱一堆锅炉板代码 此代码可编译,但在运行时使用包含以下错误的列表时会爆炸: java.lang.IllegalArgumentException:Callable需要2个参数,但提供了1个。在分派时从doSomeWork()中 此错误使我认为实例与我要添加到列表中的KFunction没有关联。
MutableListUint>
。我基本上得到了它,但我不知道如何将实例信息输入到我拥有的k函数中
这段代码有点做作,但它是我试图做的一个简单的例子。我试图通过在运行时连接分派来摆脱一堆锅炉板代码
此代码可编译,但在运行时使用包含以下错误的列表时会爆炸:
java.lang.IllegalArgumentException:Callable需要2个参数,但提供了1个。
在分派时从doSomeWork()
中
此错误使我认为实例与我要添加到列表中的KFunction
没有关联。。。但我不知道怎么把它联系起来。我手边有这个实例,我只是不知道如何附加它。或者完全是另外一回事
守则:
package reflectwork
import kotlin.reflect.KFunction
import kotlin.reflect.full.functions
import kotlin.reflect.full.hasAnnotation
import kotlin.reflect.full.memberProperties
interface Marker
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class WireMeUp
class Dispacher {
val strList = mutableListOf<(String)->Unit>()
val intList = mutableListOf<(Int)->Unit>()
val floatList = mutableListOf<(Float)->Unit>()
fun doSomeWork() {
strList.forEach { it("Some work") }
intList.forEach { it(57) }
floatList.forEach { it(3.14f) }
}
}
class Client : Marker {
@WireMeUp fun doStringWork(str:String) { println(str) }
@WireMeUp fun doIntWork(i:Int) { println(i) }
@WireMeUp fun doFloatWork(f:Float) { println(f) }
}
fun wire(app:Marker, dis:Dispacher) {
app::class.functions.forEach { func ->
if( func.hasAnnotation<WireMeUp>() ) {
require( func.parameters.size == 2 )
val parmType = func.parameters[1].type
dis::class.memberProperties.forEach{ prop ->
if( prop.returnType.arguments.size == 1 ) {
val argType = prop.returnType.arguments[0].type
// I have no idea how to compare a [type] to a ([type]) -> Unit
// so just do it via strings. better way?
if( "($parmType)->kotlin.Unit" == argType.toString().replace(" ","")) {
println("found match, setting type = $parmType")
// get the list. No idea how cast to the correct type
// which in theory I know at this point.
val lst = prop.call(dis) as MutableList<KFunction<*>>
// this works, but blows up at runtime in doSomeWork()
// with the error :
// java.lang.IllegalArgumentException: Callable expects 2 arguments, but 1 were provided.
// I think because "func" has not instance? Not sure how to attach an instance... which I have
lst.add( func )
}
}
}
}
}
}
fun main() {
val dispatch = Dispacher()
val cli = Client()
wire(cli,dispatch)
dispatch.doSomeWork()
}
包反射工作
导入kotlin.reflect.k函数
导入kotlin.reflect.full.functions
导入kotlin.reflect.full.hasAnnotation
导入kotlin.reflect.full.memberProperties
接口标记
@目标(AnnotationTarget.FUNCTION)
@保留(AnnotationRetention.RUNTIME)
注释类WireMeUp
类分派器{
val strList=mutableListOfUnit>()
val intList=mutableListoUnit>()
val floatList=mutableListoUnit>()
有趣的工作{
strList.forEach{it(“一些工作”)}
intList.forEach{it(57)}
floatList.forEach{it(3.14f)}
}
}
类客户端:标记{
@WireMeUp-fun-doStringWork(str:String){println(str)}
@WireMeUp有趣的工作(i:Int){println(i)}
@WireMeUp-fun-doFloatWork(f:Float){println(f)}
}
娱乐线(应用程序:标记器,显示器){
app::class.functions.forEach{func->
if(func.hasaAnnotation()){
需要(func.parameters.size==2)
val parmType=func.parameters[1]。类型
dis::class.memberProperties.forEach{prop->
if(prop.returnType.arguments.size==1){
val argType=prop.returnType.arguments[0]。类型
//我不知道如何将[type]与([type])->单元进行比较
//所以只要通过字符串就行了。更好的方法?
如果(“($parmType)->kotlin.Unit”==argType.toString().replace(“,”)){
println(“找到匹配项,设置类型=$parmType”)
//获取列表。不知道如何转换为正确的类型
//理论上我现在知道了。
val lst=属性调用(dis)为可变列表
//这是可行的,但在doSomeWork()中运行时会崩溃
//错误如下:
//java.lang.IllegalArgumentException:Callable需要2个参数,但提供了1个。
//我想是因为“func”没有实例?不知道如何附加实例…我有
第一次添加(函数)
}
}
}
}
}
}
主要内容(){
val dispatch=dispatcher()
val cli=Client()
连线(cli,调度)
调度。doSomeWork()
}
有什么建议吗
提前谢谢
==更新====
@kyay的回答很有效,有点假惺惺。以下是适用于上述示例的相关代码:
val lst = prop.call(dis) as MutableList<(Any)->Any>
val withInstance = { param:Any -> func.call(app, param) as Any }
lst.add( withInstance )
val lst=prop.call(dis)as MutableListAny>
val withInstance={param:Any->func.call(app,param)as Any}
lst.add(withInstance)
首先尝试将列表强制转换为(Any)->Any
的lambda列表,然后添加一个lambda,该lambda使用关联的接收器调用您的KFunction,如下所示:
println("found match, setting type = $parmType")
val lst = prop.call(dis) as MutableList<(Any) -> Any>
lst.add( { param -> func.call(myReceiverInstance, param) } ) // You just need to supply the myReceiverInstance
}
println(“找到匹配项,设置类型=$parmType”)
val lst=属性调用(dis)为可变列表任意>
lst.add({param->func.call(myReceiveInstance,param)})//您只需要提供myReceiveInstance
}
是的。必须做一些转换,但是这段代码可以工作w/@kyay的回答:val lst=prop.call(dis)as MutableListAny>val withInstance={param:Any->func.call(app,param)as Any}lst.add(withInstance)