Доступ к значению параметра функции по умолчанию в Kotlin
Можно ли получить доступ к значению параметра функции по умолчанию из расширения функции или из любого другого места?
fun DieRoll.cheatRoll():Int = roll(min = max -1)
fun roll(min: Int = 1, max: Int = 6): Int = (min..max).rand()
1 ответ:
Нет, это не возможно. Значения по умолчанию недоступны. Они просто содержатся в
bridge-method
байт-коде:fun test(a: Int = 123) { } fun test2() { test() test(100) }
Приводит к байт-коду:
public final test(int arg0) { //(I)V <localVar:index=0 , name=this , desc=Lorg/guenhter/springboot/kt/Fun;, sig=null, start=L1, end=L2> <localVar:index=1 , name=a , desc=I, sig=null, start=L1, end=L2> L1 { return } L2 { } } public static bridge test$default(org.guenhter.springboot.kt.Fun arg0, int arg1, int arg2, java.lang.Object arg3) { //(Lorg/guenhter/springboot/kt/Fun;IILjava/lang/Object;)V iload2 // reference to arg2 iconst_1 iand ifeq L1 L2 { bipush 123 // <-- THIS IS YOUR DEFAULT VALUE istore1 // reference to arg1 } L1 { aload0 // reference to arg0 iload1 // reference to arg1 invokevirtual org/guenhter/springboot/kt/Fun test((I)V); return } } public final test2() { //()V <localVar:index=0 , name=this , desc=Lorg/guenhter/springboot/kt/Fun;, sig=null, start=L1, end=L2> L1 { aload0 // reference to self iconst_0 iconst_1 aconst_null invokestatic org/guenhter/springboot/kt/Fun test$default((Lorg/guenhter/springboot/kt/Fun;IILjava/lang/Object;)V); } L3 { aload0 // reference to self bipush 100 invokevirtual org/guenhter/springboot/kt/Fun test((I)V); } L4 { return } L2 { } }
Который в синтаксисе Java будет выглядеть как
final public class AKt { final public static void test(int i) { } public static void test$default(int i, int i0, Object a) { if ((i0 & 1) != 0) { i = 123; } AKt.test(i); } final public static void test2() { AKt.test$default(0, 1, (Object)null); AKt.test(100); } }
Поэтому лучшей альтернативой для вас будет извлечение значения по умолчанию в константу:
private val DEFAULT_MIN = 1 private val DEFAULT_MAX = 1 fun DieRoll.cheatRoll():Int = roll(min = DEFAULT_MAX-1) fun roll(min: Int = DEFAULT_MIN, max: Int = DEFAULT_MAX): Int = (min..max).rand()