在 Kotlin 中按名称动态获取函数
Get function by name dynamically in Kotlin
如何在 Kotlin 中通过名称动态获取函数?
即:
fun myFunc11() { println("Very useful function 11") }
val funcName = "myFunc" + 11
val funcRef = getFunction(funcName)
funcRef()
编辑: 接受的答案似乎是正确的,但是代码目前在 Kotlin 中遇到了一些错误。已提交错误报告:https://youtrack.jetbrains.com/issue/KT-10690
在名为 Global.kt
的文件中定义的 fun myFunc11() { ... }
等全局函数被编译为名为 GlobalKt
的 class 上的 static
方法,如中所述the documentation.
要按名称获取函数引用,您需要加载定义它的 class。如果您知道定义您要查找的函数引用的文件名,您可以执行以下操作:
fun getFunctionFromFile(fileName: String, funcName: String): KFunction<*>? {
val selfRef = ::getFunctionFromFile
val currentClass = selfRef.javaMethod!!.declaringClass
val classDefiningFunctions = currentClass.classLoader.loadClass("${fileName}Kt")
val javaMethod = classDefiningFunctions.methods.find { it.name == funcName && Modifier.isStatic(it.modifiers)}
return javaMethod?.kotlinFunction
}
然后就可以找到并调用Global.kt
文件中定义的函数:
fun myFunc11() { println("Very useful function 11") }
像这样:
val kFunction = getFunctionFromFile("Global", "myFunc11")
kFunction?.call()
然而上面的内容毫无用处。更好的解决方案是搜索 classpath 中可用的所有 classes 并以 Kt
为后缀以访问所有 global 函数。然而,由于 jvm class 加载器的性质,这涉及到更多内容,如 this answer.
中所述
您可以使用 function reference operator.
::myFunc11.name
如何在 Kotlin 中通过名称动态获取函数?
即:
fun myFunc11() { println("Very useful function 11") }
val funcName = "myFunc" + 11
val funcRef = getFunction(funcName)
funcRef()
编辑: 接受的答案似乎是正确的,但是代码目前在 Kotlin 中遇到了一些错误。已提交错误报告:https://youtrack.jetbrains.com/issue/KT-10690
在名为 Global.kt
的文件中定义的 fun myFunc11() { ... }
等全局函数被编译为名为 GlobalKt
的 class 上的 static
方法,如中所述the documentation.
要按名称获取函数引用,您需要加载定义它的 class。如果您知道定义您要查找的函数引用的文件名,您可以执行以下操作:
fun getFunctionFromFile(fileName: String, funcName: String): KFunction<*>? {
val selfRef = ::getFunctionFromFile
val currentClass = selfRef.javaMethod!!.declaringClass
val classDefiningFunctions = currentClass.classLoader.loadClass("${fileName}Kt")
val javaMethod = classDefiningFunctions.methods.find { it.name == funcName && Modifier.isStatic(it.modifiers)}
return javaMethod?.kotlinFunction
}
然后就可以找到并调用Global.kt
文件中定义的函数:
fun myFunc11() { println("Very useful function 11") }
像这样:
val kFunction = getFunctionFromFile("Global", "myFunc11")
kFunction?.call()
然而上面的内容毫无用处。更好的解决方案是搜索 classpath 中可用的所有 classes 并以 Kt
为后缀以访问所有 global 函数。然而,由于 jvm class 加载器的性质,这涉及到更多内容,如 this answer.
您可以使用 function reference operator.
::myFunc11.name