Ошибка совпадения 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)
}