Получить функцию по имени динамически в Котлине

Как я могу динамически получить функцию по имени в 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

Ответ 1

Глобальные функции, такие как fun myFunc11() { ... }, определенные в файле с именем Global.kt, скомпилированы в методы static для класса с именем GlobalKt, как описано в документация.

Чтобы получить ссылку на функцию по имени, вам нужно загрузить класс, который ее определяет. Если вы знаете имя файла, которое определяет ссылку на функцию, которую вы пытаетесь найти, вы можете:

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, и суффикс с Kt для достижения всех глобальных функций. Однако из-за природы загрузчиков класса jvm это немного больше задействовано, как описано в этом ответе.