2016-03-23 4 views
1

В Scala я пытаюсь понять соответствие шаблонов, однако большинство шаблонов самоочевидны, но шаблон конструктора и переменный шаблон привязки выглядят запутанными для меня. Я попробовал следующий пример из программирования Scala, 2EDВ чем разница между шаблоном конструктора и шаблоном привязки переменных в выражении соответствия scala?

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

    } 

Я хочу знать, когда использовать конструктор шаблон

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

и когда использовать переменные картины связывания

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

Я всегда путаю в то время как он подходит к сопоставлению с образцом?

ответ

4

Конструктор против экстрактор

Узор вызове конструктора в большинстве случаев называется Extractor или Deconstructor. Это как обратный конструктор, как вы можете видеть по методу, который он называет unapply.

Если это произойдет с правой стороны или за пределами pattern match, это будет так, как вы отметили Constructor.

Ответ

@ используется только в pattern matching связать деконструкции объект переменной. Цель состоит в том, чтобы предоставить возможность поймать все выражение и по-прежнему использовать извлеченные значения на последующих этапах.

Таким образом, всегда существовал способ упорядочить код таким образом, чтобы вам не нужно было использовать @, но это могло бы облегчить читаемость.

Пример

Пример использования для @ является: Вы хотите отправить почту для всех лиц под названием «Алиса», которые старше, чем «21», но адрес не важно критериум выбор.

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

Здесь матч картина четко показывает свое намерение, подчеркивая значения, используемые для выбора и как вам нужно адрес позже для отправки почты он не будет хорошей идеей, чтобы уронить его.

+1

Очень полезный специально пример – optional