Скала неприменить метод

Я пытаюсь понять метод scala unapply.

Ниже мое понимание. Скажите, если у меня есть объект Person:

class Person(val fname: String, val lname: String)

object Person{
  def unapply(x: Person) : Option[(String, String)] = 
    Some(x.fname,x.lname)
}

new Person("Magic", "Mike") match {
  case Person(x, y) => s"Last Name is ${y}"
  case _ => "Unknown"
}

Это я предполагаю, что дело называет что-то вроде:

val temp = Person.unapply(new Person("Magic", "Mike"))
if (temp != None)  { val (x, y) = temp.get }
else { <go to next case> }

но как работает ниже неприменимо, когда у меня как ниже:

new Person("Magic", "Mike") match {
  case Person("Harold", y) => s"Last Name is ${y}"
  case Person("Magic", y) => s"Last Name is ${y}"
  case _ => "Unknown"
}

Как он получает доступ к значению fname("Magic") в методе unapply и дает мне тот же / правильный результат, что и первый?

1 ответ

Решение

Бег scalac с -Xprint:patmat покажет вам, как выглядят синтаксические деревья после фазы сопоставления с образцом:

scalac -Xprint:patmat test.scala

  case <synthetic> val x1: Person = new Person("Magic", "Mike");
  case10(){
    <synthetic> val o12: Option[(String, String)] = Person.unapply(x1);
    if (o12.isEmpty.unary_!)
      {
        <synthetic> val p3: String = o12.get._1;
        val y: String = o12.get._2;
        if ("Harold".==(p3))
          matchEnd9(scala.StringContext.apply("Last Name is ", "").s(y))
        else
          case11()
      }
    else
      case11()
  };
  case11(){
    <synthetic> val o14: Option[(String, String)] = Person.unapply(x1);
    if (o14.isEmpty.unary_!)
      {
        <synthetic> val p5: String = o14.get._1;
        val y: String = o14.get._2;
        if ("Magic".==(p5))
          matchEnd9(scala.StringContext.apply("Last Name is ", "").s(y))
        else
          case13()
      }
    else
      case13()
  };
  case13(){
    matchEnd9("Unknown")
  };

Как видите, для каждого случая сначала он вызывает unapply на подобранном объекте, то если Option не является пустым (поэтому он соответствует), он проверяет, равен ли один из элементов кортежа ожидаемому значению, если так, то соответствует ли он замыканию для этого случая.

Другие вопросы по тегам