Scala — Путаница с объектами экстрактора

Я немного запутался в экстракторе и его использовании. Я прочитал документ Scala и встретил его

object Twice {
  def apply(x: Int): Int = x * 2
  def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z/2) else None
}
object TwiceTest extends App {
  val x = Twice(21)  // x = 42
  x match { case Twice(n) => Console.println(n) } // prints 21
}`

Как распечатывается приведенный выше код, когда мы вызываем x match {case Twice(n) ..., это означает Twice(n) --> Twice.unapply(n) --> Twice.unapply(42) и получаем Some(n/2) --> Some(42/2) и снова подставляем результат в n, распечатываем 21

Если я изменю «отменить применение» следующим образом: def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z - 2) else None

То, что я получаю от консоли, это 40

Итак, я правильно понимаю?


person hminle    schedule 26.04.2016    source источник
comment
да в чем вопрос?   -  person Giovanni Caporaletti    schedule 26.04.2016
comment
Итак, теперь он изменяет n, я имею в виду, здесь он обрабатывает n как переменную. Я думаю, что это функционально, но это не так. Это сбивает меня с толку.   -  person hminle    schedule 26.04.2016
comment
n не является переменной, Twice(n) в этом контексте является шаблоном, и вы извлекаете n   -  person Giovanni Caporaletti    schedule 26.04.2016


Ответы (1)


это означает Twice(n) --> Twice.unapply(n) --> Twice.unapply(42)

Нет, Twice(n) — это шаблон (здесь он также может использоваться как выражение, но с другим значением), а Twice.unapply(n) — это выражение. И это выражение здесь не имеет смысла, потому что у вас еще нет значения для n! Вместо этого вызывается Twice.unapply(x).

x match { case Twice(n) => ...expression_using_n; ...other cases } в основном такой же, как

Twice.unapply(x) match { 
  case Some(n) => ...expression_using_n
  case None => x match { ...other cases }
}

Или убрать цикличность, так как Some сам по себе является объектом-экстрактором:

val unapplied = Twice.unapply(x)
if (unapplied.isDefined) {
  val n = unapplied.get
  ...expression_using_n
} else 
  x match { ...other cases }
person Alexey Romanov    schedule 26.04.2016