web-dev-qa-db-fra.com

Kotlin: const val vs val

Je comprends dans Kotlin const val Est utilisé pour déclarer des constantes et val pour les propriétés en lecture seule. Cependant, je me demande dans le cas suivant lequel est le plus approprié.

Supposons que j'ai un fragment qui nécessite une clé à utiliser pour saveInstanceState et restoreInstanceState. Je me demande laquelle des deux options suivantes est la meilleure:

Option 1:

class MyFragment {
    private val MY_KEY = "my_key"
    ...
}

Option 2:

private const val MY_KEY = "my_key" // declared in the same file.

class MyFragment {
    ...
}

Je préférerais l'option #option 2 car elle indique clairement que MY_KEY Est une constante et que la valeur est déterminée lors de la compilation. Cependant, comme il est déclaré au niveau supérieur, il en coûte une classe, à savoir MyFragmentKt (supposons que le nom du fichier est MyFragment.kt) Pour être créé dans le répertoire compilé Java Dans #option 1, aucune classe supplémentaire n'est générée et bien que la valeur de MY_KEY Soit affectée à l'exécution et non constante, cela ne fait aucune différence dans son utilisation dans ce cas spécifique.

Donc, bien que je préfère personnellement #option 2, mon analyse me fait penser que #option 1 n’est pas pire, sinon mieux. Je me demande simplement comment les autres développeurs pensent à ce sujet et s'il existe d'autres avantages de #option 2 auxquels je n'ai pas pensé. Merci.

29
H.Nguyen

Chaque fois que vous écrivez une expression lambda (non en ligne), vous créez une autre classe. Par rapport à cela, créer une seule classe pour contenir des déclarations de niveau supérieur semble mineur.

De plus, si tout ce que vous avez au niveau supérieur est une déclaration constante, elle sera insérée dans chaque site d'utilisation (par spécification), de sorte que la classe propriétaire ne sera plus référencée et donc ciblable par la minimisation de ProGuard. Il n'apparaîtra probablement pas dans votre APK de production.

19
Marko Topolnik

Il n'y a pas qu'une différence sémantique entre les deux options.

L'option 1 (val à l'intérieur de la classe) est un champ d'instance.

Option 2 (niveau supérieur const val) est un membre "statique" de niveau supérieur (en gros, puisque static n'existe pas dans Kotlin.)

C'est pourquoi vous avez généré une classe MyFragmentKt: les membres de niveau supérieur sont compilés dans une classe du nom [Filename]Kt.

Je considérerais une troisième option:

class MyFragment {
    companion object {
        private const val MY_KEY = "my_key"
    }
}

Par ici, MY_KEY est (à partir de Java) un membre static de la classe MyFragment, puisque JvmStatic est inféré pour les variables const. Une classe Companion sera générée (mais elle sera vide).

Puisque votre approche initiale était un domaine dans la classe, je me sens comme le companion object/static constante peut être préférable.

Plus à propos companion objects vs Java's static

12
Moira