2017-06-28 7 views
5

निम्नलिखित समारोहऔर का उपयोग कर डिफ़ॉल्ट पैरामीटर

fun function(x: Int = 12) { 
    println("x = $x") 
} 

को देखते हुए मैं प्रतिबिंब कैसे का उपयोग कर सकते हैं x निर्दिष्ट किए बिना यह आह्वान (या किसी भी तरह डिफ़ॉल्ट मान का उपयोग कर, मुश्किल यह कोडिंग नहीं)?

उत्तर

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(), "") 
संबंधित मुद्दे