2017-06-28 11 views

Trả lời

6

Bạn có thể sử dụng callBy, mà tôn trọng các giá trị mặc định:

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

Mọi thứ sẽ lộn xộn nếu bạn có nhiều thông số không có giá trị mặc định:

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

Nó sẽ còn nhàm chán hơn nếu hàm của bạn là một hàm thành viên của một kiểu không phải là đối tượng hoặc hàm mở rộng của nó, hoặc đó là một hàm mở rộng cho một kiểu như là một hàm thành viên của một kiểu không phải đối tượng (khác).

Tôi đã viết một phương pháp thuận tiện để giảm soạn sẵn:

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

Cách sử dụng:

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(), "") 
Các vấn đề liên quan