2016-03-23 13 views
1

In Scala versuche ich, Mustererkennung zu verstehen, aber die meisten der Muster sind selbsterklärend, aber Konstruktormuster und variable Bindungsmuster sehen für mich verwirrend aus. Ich habe versucht, aus Programming Scala folgenden Beispiel 2edWas ist der Unterschied zwischen Konstruktormuster und variablem Bindungsmuster in einem Scala-Übereinstimmungsausdruck?

case class Address(street: String, city: String, country: String) 
case class Person(name: String, age: Int, address: Address) 

object ScalaCaseDemoMain extends App{ 

    val alice = Person("Alice", 25, Address("1 Scala Lane", "Chicago", "USA")) 
    val bob  = Person("Bob",  29, Address("2 Java Ave.", "Miami", "USA")) 
    val charlie = Person("Charlie", 32, Address("3 Python Ct.", "Boston", "USA")) 

    for (person <- Seq(alice, bob, charlie)) { 
    person match { 
     case p @ Person("Alice", 25, address) => println(s"Hi Alice! $p") 
     case p @ Person("Bob", 29, a @ Address(street, city, country)) => 
     println(s"Hi ${p.name}! age ${p.age}, in ${a.city}") 
     case p @ Person(name, age, _) => 
     println(s"Who are you, $age year-old person named $name? $p") 
    } 
} 

    } 

Ich möchte wissen, wenn Konstruktor Muster

case Person("Alice", 25, address) => //some action here 

zu verwenden und wenn variable Bindungsmuster verwenden

case p @ Person("Alice", 25, address) //some action here 

Ich bin immer verwirrt Während es um Mustervergleich geht?

Antwort

4

Constructor vs Extractor

Das Muster, das Sie Konstruktor genannt einen Extractor oder Deconstructor in den meisten Fällen rufen. Es ist wie ein umgekehrter Konstruktor, wie Sie durch die Methode sehen können, die es unapply aufruft.

Wenn es auf der rechten Seite oder außerhalb der pattern match auftreten würde, wäre es wie Sie eine Constructor notiert.

Antwort

@ nur in pattern matching verwendet wird, um die zerlegten Einheit an eine Variable zu binden. Zweck ist es, die Option bereitzustellen, den gesamten Ausdruck abzufangen und trotzdem in späteren Schritten extrahierte Werte verwenden zu können.

So würde es immer eine Möglichkeit geben, den Code in einer Weise anzuordnen, die Sie @ nicht verwenden müssten, aber es könnte Lesbarkeit viel helfen.

Beispiel

Ein Anwendungsbeispiel für @ ist: Sie mögen eine Mail an alle Personen „Alice“, die als „21“ älter sind genannt senden, aber die Adresse ist kein wichtiges Auswahlkriterium.

case p @ Person("Alice", age, _) if age > 21 => storePersonForMailing(p) 

Hier ist die Mustererkennung zeigt deutlich, Ihre Absicht, indem sie die Werte betonen Sie für die Auswahl verwenden und wie Sie die Adresse später zum Senden der Mail müssen wäre es keine gute Idee, es fallen zu lassen.

+1

Sehr hilfreiches Beispiel – optional