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