2016-01-16 46 views
10

Kotlinで関数を名前で動的に取得するにはどうすればよいですか?Kotlinで動的に名前で関数を取得

すなわち:

fun myFunc11() { println("Very useful function 11") } 

val funcName = "myFunc" + 11 
val funcRef = getFunction(funcName) 

funcRef() 

編集:受け入れ答えは、しかし、コードが現在Kotlinにいくつかのバグに当たっている、正しいように見えます。バグレポートが提出さ:the documentationで説明したように、すなわちGlobal.ktという名前のファイルに定義されているなどfun myFunc11() { ... }などhttps://youtrack.jetbrains.com/issue/KT-10690

+0

名前で関数を呼び出す代わりに関数参照を使用することを検討しましたか? –

+0

私は動的に関数リファレンスを取得したいと思います。 –

答えて

8

グローバル関数がGlobalKtという名前のクラスのstaticメソッドにコンパイルされています。

関数参照を名前で取得するには、名前を定義するクラスを読み込む必要があります。あなたが見つけることをしようとしている関数のリファレンスを定義するファイルの名前を知っている場合は行うことができます。

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() 

しかし、上記はかなり役に立たないです。クラスパスで利用可能なすべてのクラスを検索し、末尾にKtを追加して、すべてグローバルの関数に到達するとよいでしょう。しかし、jvmクラスローダーの性質上、これはthis answerで説明されているようにもう少し複雑です。

+0

これは正しいと思われるので、私はこの回答を受け入れていますが、現在例外が発生しています: 'kotlin.reflect.KotlinReflectionInternalError:呼び出しはこの関数ではまだサポートされていません '。 Kotlin 1.0.0-beta-4584 –

+0

@AmirAbiriはあなたが 'kotlin.reflect'でいくらかぎこちなかったようです。 – miensol

+0

はい私はケースを一般化してBRを提出しました。 –

関連する問題