2017-06-28 16 views

Odpowiedz

6

Można użyć callBy, które szanuje wartości domyślne:

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

Co będzie bałagan, jeśli masz wiele parametrów bez wartości domyślne:

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

To będzie jeszcze bardziej nudny jeśli twoja funkcja jest funkcją składową typu nieobiektowego lub jego funkcją rozszerzenia lub jest funkcją rozszerzenia dla typu jako funkcji składowej (innego) typu nieobiektowego.

pisałem wygodny sposób, aby zmniejszyć boilerplate:

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

Zastosowanie:

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(), "") 
Powiązane problemy