Scala: Attention aux gardes dans les pattern matching

Publié le 25 Septembre 2015

Je viens de tomber sur un comportement du compilateur Scala auquel je ne m'attendais pas et qui peux s'avérer assez pernicieux si le développeur n'a pas conscience de ce fonctionnement.

 

Ceci concerne les pattern matching. Lorsqu'on "pattern match" sur un sealed trait le compilateur peut vérifier que tout les cas sont couvert. Par exemple:

 

sealed trait Record
case class InputRecord(input: String) extends Record
case class OutputRecord(output: String) extends Record

def logRecord(record: Record): Unit = record match {
  case in: InputRecord => println(s"Input record: $in")
  case out: OutputRecord => println(s"Output record: $out")
}

Là pas de problème le pattern match couvre les 2 sous-classes de Record et la compilation passe. Maintenant si j'oublie de traiter un cas:

 

def logRecord(record: Record): Unit = record match {
  case out: OutputRecord => println(s"Output record: $out")
}

Le compilateur le détecte est remonte une erreur car les InputRecord ne sont pas couvert. Super! C'est ce que j'attends du compilateur. Ce qui est plus surprenant maintenant est l'ajout d'une garde (un if quoi):

 

def logRecord(record: Record): Unit = record match {
  case out: OutputRecord if (!out.output.isEmpty) =>
    println(s"Output record: $out")
}

 

On est toujours dans le même cas que précédemment: les InputRecord ne sont pas traités. C'est même pire certains OutputRecord ne sont pas traités. Et pourtant scalac ne remonte aucune erreur, pas même un petit warning.

 

Je comprends bien que le compilateur ne peut pas analyser mon if mais il pourrait assumer que cela couvre les OutputRecord (tout au plus) et sortir une erreur pour les InputRecord (ou plus simplement afficher un warning comme quoi ce pattern match n'a pu être vérifier).

 

Pour plus d'info il y a un bug ouvert à ce sujet: https://issues.scala-lang.org/browse/SI-7631?jql=labels%20%3D%20pattern-matching

Rédigé par Bliz

Publié dans #Scala

Repost 0
Commenter cet article