2017-06-28 55 views
5

(或以某種方式使用默認值,硬編碼它)?

回答

6

可以使用callBy,哪些方面的默認值:

::function.callBy(emptyMap()) // is just function() 

事情會混亂,如果你有很多參數沒有默認值:

fun foo(a: Int, b: String = "") {} 
val ref = ::foo 
val params = ref.parameters 
ref.callBy(mapOf(params[0] to 1)) // is just foo(1) 

這將是,如果更無聊了你的函數是非對象類型的成員函數,或者它是擴展函數,或者它是類型作爲(其他)非對象類型的成員函數的擴展函數。

我寫了一個方便的方法來減少樣板:

fun <R> KFunction<R>.callNamed(params: Map<String, Any?>, self: Any? = null, extSelf: Any? = null): R { 
    val map = params.entries.mapTo(ArrayList()) { entry -> 
     parameters.find { name == entry.key }!! to entry.value 
    } 
    if (self != null) map += instanceParameter!! to self 
    if (extSelf != null) map += extensionReceiverParameter!! to extSelf 
    return callBy(map.toMap()) 
} 

用法:

fun String.foo(a: Int, b: String = "") {} 
fun foo(a: Int, b: String = "") {} 
class Foo { 
    fun bar(a: Int, b: String = "") {} 
    fun String.baz(a: Int, b: String = "") {} 
} 

::foo.callNamed(mapOf("a" to 0)) 
String::foo.callNamed(mapOf("a" to 0), extSelf = "") 
Foo::bar.callNamed(mapOf("a" to 0), Foo()) 
// function reference don't work on member extension functions 
Foo::class.declaredFunctions.find { it.name == "baz" }!!.callNamed(mapOf("a" to 0), Foo(), "") 
相關問題