給定一個字串名稱串列,是否可以從特定值動態呼叫正確的方法?
在這個例子中, invokeMethod 是組成的,但它是我理想中需要的。第一個引數是要呼叫的方法名稱,第二個引數是引數串列。
class MethodPicker() {
val commands = listOf("foo", "tango")
fun messageReceiver() {
messageParam : String = "Hi stackoverflow!"
invokeMethod(commands.random(), messageParam) //HOW TO DO THIS IN KOTLIN?, the first parameter is the methodf name and the second one would be the parameters that the method receives
}
fun foo(message: String) {
println(message "foo!")
}
fun tango(message: String) {
println(message "tango!")
}
}
uj5u.com熱心網友回復:
可能有一種方法可以使用反射來做到這一點——但這應該只是最后的手段。(它可能是冗長的、脆弱的、緩慢的、難以維護和不安全的。對于框架、插件和編譯器工具很方便;但對于一般編程,通常有更好的方法。)
除了名稱之外,這里的一種方法是存盤對它應該呼叫的函式的參考。
您可以使用這樣的簡單類來存盤它們:
class Method(val name: String, val method: (String) -> Unit)
((String) -> Unit是采用單個 String 引數且不回傳有用值的函式型別。)
您的命令串列可能是:
val commands = listOf(Method("foo", ::foo), Method("tango", ::tango))
(::給你一個方法/函式的可呼叫參考。因為foo()andtango()是實體方法,你通常必須提供實體來呼叫它們,例如myInstance::foo- 但因為串列是在實體方法中定義的,編譯器已經知道.)
你可以呼叫一個隨機函式:
commands.random().method(messageParam)
列出名稱和參考可能看起來有點冗長,但它更高效、更安全:編譯器可以在運行時檢查所有內容,您甚至可以將顯示的字串翻譯成不同的語言,而無需重寫所有內容編碼。)
uj5u.com熱心網友回復:
如果您確實需要接受來自函式字串名稱的用戶的輸入,我建議將它們按名稱存盤在 Map 中。
private val commandsByName = listOf(::foo, ::tango).associateBy { it.name }
fun messageReceiver(method: String, message: String) {
commandsByName[method]!!(message)
// or
commandsByName[method]?.invoke(message) ?: error("Unknown method: $method")
// or
commandsByName[method]?.invoke(message) // to fail silently
}
fun randomMessageReceiver(message: String) {
commandsByName.values.random()(message)
}
如果你不這樣做,只需一個串列就可以了。
private val commands = listOf(::foo, ::tango)
fun randomMessageReceiver(message: String) {
commands.random()(message)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/323378.html
標籤:科特林
