49 votes

Forcer l'erreur de compilation avec les classes scellées

Avec les classes scellées, vous pouvez utiliser des when et omettre l'expression else lorsque l'expression renvoie un résultat :

sealed class SealedClass {
  class First : SealedClass()
  class Second : SealedClass()
}

fun test(sealedClass: SealedClass) : String =
    when (sealedClass) {
      is SealedClass.First -> "First"
      is SealedClass.Second -> "Second"
    }

Maintenant, si je devais ajouter un Third à SealedClass le compilateur se plaindra que l'option when l'expression dans test() n'est pas exhaustive, et je dois ajouter une clause de Third o else .

Je me demande cependant si ce contrôle peut également être appliqué lorsque test() ne renvoie rien :

fun test(sealedClass: SealedClass) {
    when (sealedClass) {
      is SealedClass.First -> doSomething()
      is SealedClass.Second -> doSomethingElse()
    }
}

Cet extrait n'est pas cassé si Third est ajouté. Je peux ajouter un return déclaration avant when mais cela peut facilement être oublié et peut être rompu si le type de retour de l'une des clauses n'est pas Unit .

Comment puis-je m'assurer que je n'oublie pas d'ajouter une branche à mon when clauses ?

2 votes

J'ai posé la même question dans Slack il y a longtemps, et AFAIR, il n'y a pas de solution autre que d'en faire une expression renvoyant quelque chose. Mais IntelliJ devrait émettre un avertissement si vous oubliez une clause, cependant (ma question concernait un enum, pas une classe scellée, mais cela devrait être la même chose).

1 votes

Hmm, oui. J'ai remarqué que je peux le faire revenir Any? et de forcer une valeur de retour, mais cela semble toujours un peu compliqué.

0 votes

Mon préféré est le bloc run. Il est lisible, ne change pas le type de retour de la fonction de Unit à Any ?, et n'est pas plus ou moins oubliable que l'ajout d'un type de retour return ou Any ?

1voto

fkdplc Points 21

Pensez à utiliser la récente bibliothèque de JakeWharton qui permet d'utiliser simplement @Exhaustive annotation.

sealed class RouletteColor {
  object Red : RouletteColor()
  object Black : RouletteColor()
  object Green : RouletteColor()
}

fun printColor(color: RouletteColor) {
  @Exhaustive
  when (color) {
    RouletteColor.Red -> println("red")
    RouletteColor.Black -> println("black")
  }
}

Utilisation :

buildscript {
  dependencies {
    classpath 'app.cash.exhaustive:exhaustive-gradle:0.1.1'
  }
  repositories {
    mavenCentral()
  }
}

apply plugin: 'org.jetbrains.kotlin.jvm' // or .android or .multiplatform or .js
apply plugin: 'app.cash.exhaustive'

Lib : https://github.com/cashapp/exhaustive

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X