2010-10-25 11 views
7

Ich möchte die Warnung nutzen, die Scala gibt, wenn ein Abgleich fehlt ("nicht erschöpfend") - damit ich einen nicht vergesse (ich habe Dutzende). Das folgende vereinfachte Beispiel zeigt meinen Versuch:Scala Pattern Matching sagt immer "Match ist nicht erschöpfend!"

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) 
    } 
} 

Das Problem ist, dass es sagt, "Match ist nicht erschöpfend!" obwohl alle möglichen Kombinationen aufgeführt sind. Wenn ich das setzen würde „Fall _ =>“ dort wird der ganze Sinn der Warnung für mich für ungültig erklärt, weil ich

class INFO_MESSAGE extends MESSAGE 

und keine Warnung ausgegeben würde hinzufügen könnte.

Gibt es eine Lösung?

+6

SUCCESS_MESSAGE sollte drucken "failure:" sind Sie ganz sicher? –

+2

Ich würde sehr empfehlen, eine Fallklasse in jedem Fall zu erweitern. Nur zu deiner Information. – jsuereth

Antwort

32

Idealerweise sollten Sie keine konkrete Klasse erweitern, insbesondere keine Fallklasse!

Vorausgesetzt, dass es keine Möglichkeit gibt, SUCCESS_MESSAGE und FAILURE_MESSAGE anzupassen, möchten Sie wahrscheinlich auch diese Singletons machen.

Schließlich sind Unterstriche ein Bad Thing (tm) in Scala Variablen oder Klassennamen. Alle UPPERCASE-Namen sind auch nicht idiomatisch. Also:

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) 
} 

Alternativ und ich würde dies empfehlen, können Sie die aktuelle Nachrichtenkette wickeln:

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/in Scala Variablennamen/in Scala Klassennamen/ –

+0

Variable ODER Klassennamen, wenn Sie genau sein wollen :) –

+2

Das erste Beispiel leidet immer noch unter dem gleichen Problem, da 'Message' nicht als 'abstrakt' gekennzeichnet ist. Das zweite Beispiel ist in Ordnung, weil die abstrakte Methode 'msg' garantiert, dass 'Message' ebenfalls abstrakt ist. –

27

Sie haben einen Fall übersehen: Die Nachricht könnte eine Instanz von MESSAGE sein, keine ihrer Unterklassen. Wenn Sie diesen Fall unmöglich machen möchten, müssen Sie MESSAGE abstract machen. Dies wird die Warnung verschwinden lassen.