Ошибка совпадения Scala с отменой

Я пробую код на http://www.scala-lang.org/node/112 и получаю ошибку соответствия для чего-то, что не похоже на то, что оно должно сгенерировать.

Это оригинальный код:

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 Application {
  val x = Twice(21)
  x match { case Twice(n) => Console.println(n) } // prints 21
}

Я просто добавил несколько строк, чтобы проверить, что происходит, когда я пропускаю нечетное число:

object TwiceTest extends Application {
  val x = Twice(21)
  x match { case Twice(n) => Console.println(n) } // prints 21
  val y = 21
  y match { case Twice(n) => Console.println(n) } // throws scala.MatchError: 21 (of class java.lang.Integer)
}

Насколько я могу судить, регистр 21 или любого нечетного числа также должен обрабатываться методом unapply в объекте. Может кто-нибудь объяснить, почему это не так?

2 ответа

Решение
val x = Twice(21)

такой же как

val x = Twice.apply(21)

означающий, что x будет равен 42, Twice.unapply(42) возвращает Some(21)Это означает, что case Twice(21) успешно соответствует значению x == 42,

Вот почему первый match заявление распечатывается 21,

Twice.unapply(21) возвращается None (так как y == 21то есть если y странно). Всякий раз, когда unapply возвращается None для некоторого значения мы говорим, что объект экстрактора с этим unapply Метод не соответствует этому значению.

Если match оператор не соответствует значению ни в одном из своих случаев, он бросит MatchError,

Это обрабатывается вашим unapply метод, но не match, Так как ваш unapply должен вернуть None, это означает, что это не соответствует case Twice(n),

Измените это на что-то вроде

21 match {
  case Twice(n) => println("this won't happen")
  case x => println("just " + x)
}
Другие вопросы по тегам