2010-10-25 4 views
7

Je veux tirer parti de l'avertissement que Scala émet quand une correspondance est manquante ("non exhaustive") - pour que je n'en oublie pas une (j'en ai des douzaines). L'exemple simplifié suivant montre ma tentative:Scala motif correspondant continuer à dire "match n'est pas exhaustive!"

sealed case class MESSAGE() 
class SUCCESS_MESSAGE extends MESSAGE 
class FAILURE_MESSAGE extends MESSAGE 

def log(str: String, msgType: MESSAGE) { 
    msgType match { 
     case t:SUCCESS_MESSAGE => println("FAILURE: " + str) 
     case t:FAILURE_MESSAGE => println("SUCCESS: " + str) 
    } 
} 

Le problème est qu'il est écrit "correspondance non exhaustive!" bien que toutes les combinaisons possibles soient répertoriées. Si je mets le « cas _ => » là-bas, le point de l'ensemble de l'avertissement est invalidée pour moi parce que je pourrais ajouter

class INFO_MESSAGE extends MESSAGE 

et aucun avertissement ne sera émis.

Existe-t-il une solution?

+6

SUCCESS_MESSAGE doit imprimer "NON", êtes-vous bien sûr? –

+2

Je recommande fortement de ne pas étendre une classe de cas en aucune circonstance. Juste FYI. – jsuereth

Répondre

32

Idéalement, vous ne devriez pas étendre une classe concrète, et surtout pas une classe de cas!

Étant donné qu'il n'y a pas de potentiel pour personnaliser SUCCESS_MESSAGE et FAILURE_MESSAGE, vous voudrez probablement aussi faire ces singletons. Enfin, les caractères de soulignement sont une mauvaise chose (tm) dans les noms de variable ou de classe Scala. Tous les noms UPPERCASE ne sont pas non plus idiomatiques. Alors:

sealed trait Message 
case object SuccessMessage extends Message 
case object FailureMessage extends Message 

def log(str: String, msgType: Message) = msgType match { 
    case SuccessMessage => println("Success: " + str) 
    case FailureMessage => println("Failure: " + str) 
} 

Sinon, et je serait recommander, vous pouvez envelopper la chaîne de message réel:

sealed trait Message { def msg: String } 
case class Success(msg:String) extends Message 
case class Failure(msg:String) extends Message 

def log(msg: Message) = msg match { 
    case Success(str) => println("Success: " + str) 
    case Failure(str) => println("Failure: " + str) 
} 
+0

s/dans les noms de variable Scala/dans les noms de classe Scala/ –

+0

variable Noms de classe OU, si vous voulez être exact :) –

+2

Le premier exemple souffre toujours du même problème, puisque 'Message' n'est pas marqué' abstract'. Le deuxième exemple est correct car la méthode abstraite 'msg' garantit que' Message' est également abstrait. –

27

Vous avez manqué un cas: Le message peut être une instance de MESSAGE, et non une de ses sous-classes.

Si vous voulez rendre ce cas impossible, vous devez faire MESSAGE abstrait. Cela fera disparaître l'avertissement.

Questions connexes