Correspondance exhaustive
Complétude vérifiée par le compilateur
Correspondance exhaustive est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Scala for Backend Engineering & Functional Programming, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.
Qu’est-ce qu’une correspondance exhaustive ?
Une correspondance est exhaustive lorsqu’elle gère toutes les valeurs possibles du type traité.
Pour un trait scellé, le compilateur connaît toutes les variantes et peut vérifier que votre correspondance les couvre toutes.
Une correspondance complète
Lorsque vous gérez chaque variante d’un trait scellé, le compilateur est satisfait et aucun avertissement n’apparaît.
sealed trait Color
case object Red extends Color
case object Green extends Color
case object Blue extends Color
object Main {
def name(c: Color): String = c match {
case Red => "red"
case Green => "green"
case Blue => "blue"
}
def main(args: Array[String]): Unit = {
println(name(Blue))
}
}Le compilateur veille sur vous
Si vous oubliez une variante, le compilateur émet un avertissement de correspondance non exhaustive au moment de la compilation.
C’est un filet de sécurité : vous découvrez l’oubli avant d’exécuter le programme.
Ajouter une variante plus tard
Le véritable avantage apparaît lorsque vous ajoutez une nouvelle variante. Chaque correspondance non exhaustive dans votre base de code signale un avertissement, vous rappelant de gérer le nouveau cas.
Le remaniement devient ainsi sûr et prévisible.
Pourquoi éviter un caractère générique
Ajouter case _ => masque les avertissements de couverture exhaustive. Cela peut dissimuler des bogues lorsque vous ajoutez des variantes ultérieurement.
Pour les ADT scellés, préférez énumérer explicitement chaque variante afin que le compilateur continue à vous protéger.
sealed trait Status
case object Active extends Status
case object Inactive extends Status
object Main {
def label(s: Status): String = s match {
case Active => "on"
case Inactive => "off"
}
def main(args: Array[String]): Unit = {
println(label(Active))
}
}Exhaustivité avec des données
L’exhaustivité s’applique également aux variantes qui contiennent des données. Vous liez les champs, tout en devant couvrir chaque variante.
sealed trait Shape
case class Circle(r: Double) extends Shape
case class Square(s: Double) extends Shape
object Main {
def area(sh: Shape): Double = sh match {
case Circle(r) => 3.14159 * r * r
case Square(s) => s * s
}
def main(args: Array[String]): Unit = {
println(area(Circle(2)))
println(area(Square(3)))
}
}Combiner avec des gardes
Soyez prudent : les gardes peuvent rendre une correspondance non exhaustive, car le compilateur ne peut pas prouver qu’elles couvrent toutes les valeurs.
Ajoutez un dernier cas sans garde pour la même variante afin de rester exhaustif.
sealed trait Temp
case class Celsius(v: Int) extends Temp
object Main {
def feel(t: Temp): String = t match {
case Celsius(v) if v >= 30 => "hot"
case Celsius(v) => "not hot"
}
def main(args: Array[String]): Unit = {
println(feel(Celsius(35)))
println(feel(Celsius(10)))
}
}Exhaustivité avec Option
La bibliothèque standard fournit Option, un ADT scellé avec Some et None. Faire correspondre les deux rend la correspondance exhaustive.
object Main {
def show(o: Option[Int]): String = o match {
case Some(v) => s"value $v"
case None => "nothing"
}
def main(args: Array[String]): Unit = {
println(show(Some(7)))
println(show(None))
}
}Exhaustivité imbriquée
L’exhaustivité aide également avec les ADT imbriqués. Le compilateur raisonne sur chaque niveau que vous déstructurez.
sealed trait Tree
case object Leaf extends Tree
case class Node(v: Int, l: Tree, r: Tree) extends Tree
object Main {
def depth(t: Tree): Int = t match {
case Leaf => 0
case Node(_, l, r) => 1 + math.max(depth(l), depth(r))
}
def main(args: Array[String]): Unit = {
println(depth(Node(1, Leaf, Node(2, Leaf, Leaf))))
}
}Pourquoi est-ce important ?
La vérification de l’exhaustivité par le compilateur vous apporte :
- la certitude que chaque cas est géré
- des rappels automatiques lorsque l’ADT évolue
- moins de MatchErrors à l’exécution
- un remaniement à grande échelle plus sûr
Assembler le tout
Un ADT scellé avec une couverture complète. L’ajout d’une nouvelle variante déclencherait ici un avertissement du compilateur.
sealed trait Command
case object Start extends Command
case object Stop extends Command
case class SetSpeed(v: Int) extends Command
object Main {
def run(c: Command): String = c match {
case Start => "starting"
case Stop => "stopping"
case SetSpeed(v) => s"speed $v"
}
def main(args: Array[String]): Unit = {
List(Start, SetSpeed(5), Stop).foreach(c => println(run(c)))
}
}Vérification rapide
Vérifiez votre compréhension de la correspondance exhaustive.
Récapitulatif
Vous avez découvert la correspondance exhaustive :
- une correspondance est exhaustive lorsqu’elle couvre chaque variante
- pour les traits scellés, le compilateur le vérifie et signale les oublis
- l’ajout d’une variante révèle chaque correspondance incomplète
- évitez
case _sur les ADT scellés pour conserver cette protection - les gardes peuvent rompre l’exhaustivité ; ajoutez un cas de repli sans garde
Questions Fréquemment Posées
La leçon « Correspondance exhaustive » est-elle gratuite ?
Oui — le texte complet de « Correspondance exhaustive » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Scala for Backend Engineering & Functional Programming, passe à CoddyKit PRO. Le cours Scala for Backend Engineering & Functional Programming comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Correspondance exhaustive » ?
Complétude vérifiée par le compilateur Tu pratiques Scala for Backend Engineering & Functional Programming avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Scala for Backend Engineering & Functional Programming ?
Aucune expérience préalable n'est requise. Scala for Backend Engineering & Functional Programming sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Correspondance exhaustive » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Scala for Backend Engineering & Functional Programming ?
Oui. Chaque leçon Scala for Backend Engineering & Functional Programming inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Classes case
- Traits scellés
- Types de données algébriques
- Correspondance exhaustive