2017-08-20 6 views
4

La valeur de paramètre par défaut d'une fonction peut-elle être accédée à partir d'une extension de fonction, ou ailleurs?Accès à la valeur de paramètre par défaut d'une fonction dans Kotlin

fun DieRoll.cheatRoll():Int = roll(min = max -1) 

fun roll(min: Int = 1, max: Int = 6): Int = (min..max).rand() 
+6

Non, ça ne peut pas. Puisqu'une valeur par défaut d'un paramètre peut être une expression aribtraire avec des effets secondaires possibles, il ne serait pas très clair et intuitif de l'utiliser n'importe où explicitement: quelle devrait être la sémantique, devrait-elle être évaluée sur chaque utilisation ou non? – hotkey

+0

Qu'en est-il juste de stocker les valeurs min et max comme des constantes? Cela rendrait la visibilité de l'accès meilleure aussi. – creativecreatorormaybenot

Répondre

3

Non, ce n'est pas possible. Les valeurs par défaut ne sont pas accessibles. Ils sont simplement contenus dans un bridge-method dans le bytecode:

fun test(a: Int = 123) { 
} 

fun test2() { 
    test() 
    test(100) 
} 

Les résultats du bytecode:

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 { 
    } 
} 

donc la meilleure solution pour vous serait d'extraire la valeur par défaut dans une constante:

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