2016-04-24 4 views
2

am Scala doc for sealed classes Sehen, heißt es:Selector von Mustererkennung abschließend ist

Wenn der Wähler einer Mustererkennung ist eine Instanz einer versiegelten Klasse, die Erstellung von Musterabgleich Warnungen ausgeben, kann die Diagnose, dass ein Die angegebene Menge von Mustern ist nicht erschöpfend, dh es besteht die Möglichkeit, dass zur Laufzeit ein MatchError ausgelöst wird.

Ich verstehe nicht ganz, was sie in diesem Absatz meinten. Mein Verständnis ist, dass, wenn ein Switch-Fall, nicht alle Möglichkeiten umfasst, wir eine Warnung bei der Kompilierung bekommen, sagen wir könnten einen Fehler zur Laufzeit bekommen. Ist das richtig?

Ich finde es seltsam, denn wie können wir ALLE Szenarien in einem Switch-Fall abdecken? Wir müssten alle möglichen Zeichenfolgen abgleichen, was nur albern ist, also nehme ich an, mein Verständnis ist inkorrekt. Jemand interessiert es bitte, aufzuklären?

Antwort

3

Ich finde es seltsam, denn wie können wir ALLE Szenarien in einem Switch-Fall abdecken? Wir würden alle möglichen Strings entsprechen

Ja, wenn der Wähler String hat geben (außer es kein sealed Klasse ist, denn das ist ein Scala-Konzept ist und String ist eine Java-Klasse).

, die für Strings

No. nur dumm ist, brauchen Sie nur einen allumfassenden Fall, z.B.

val x: String = ... 
x match { 
    case "a" => ... 
    case "b" => ... 
    case _ => ... 
} 

ist ein erschöpfendes Spiel: was auch immer x ist, paßt es einer der Fälle. Sinnvoller, können Sie haben:

val x: Option[A] = ... 
x match { 
    case Some(y) => ... 
    case None => ... 
} 

und der Compiler wird das Spiel vollständig ist auch ohne catch-all Fall bewusst sein.

4

Was ist der Absatz sagt, ist, dass im Fall, dass Sie eine feste Hierarchiestruktur wie diese:

sealed trait Foo 
class Bar extends Foo 
class Baz extends Foo 
class Zab extends Foo 

Dann, wenn Sie Mustererkennung auf sich, kann der Compiler ableiten, wenn Sie versucht haben, auf Übereinstimmen den versiegelten Zug, in diesem Beispiel alle möglichen Arten erstrecken:

def f(foo: Foo) = foo match { 
    | case _: Bar => println("bar") 
    | case _: Baz => println("baz") 
    | } 

<console>:13: warning: match may not be exhaustive. 
It would fail on the following input: Zab() 
     def f(foo: Foo) = foo match { 
         ^
f: (foo: Foo)Unit 

Hinweis der Anfang des document sagt:

Eine versiegelte Klasse darf nicht direkt vererbt werden, es sei denn, die erbende Vorlage ist in derselben Quelldatei wie die geerbte Klasse definiert.

Dies ist einzigartig für Scala und kann nicht in Java durchgeführt werden. Eine final Klasse in Java kann nicht vererbt werden, auch wenn sie in derselben Datei deklariert ist. Aus diesem Grund funktioniert diese Logik nicht für String in Scala, einem Alias ​​für java.lang.String. Die Compiler-Warnung darf nur für Scala-Typen ausgegeben werden, die den obigen Kriterien entsprechen.

0

Das Platzhalterzeichen erlaubt uns, alle Szenarien abzudecken.

something match { 
    case one => ... 
    case two => ... 
    case _ => ... 
} 

Sie wird ausgewählt, wenn alle anderen Fälle nicht übereinstimmen. das ist der Standardfall. Weitere Informationen here.