Scala匹配错误与unapply

时间:2012-06-25 13:28:12

标签: scala pattern-matching unapply

我正在试用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 个答案:

答案 0 :(得分:6)

val x = Twice(21)

相同
val x = Twice.apply(21)

意味着x将等于42Twice.unapply(42)返回Some(21),表示case Twice(21)成功匹配值x == 42

这就是第一个match语句打印出21

的原因

Twice.unapply(21)返回None(因为y == 21,即y是奇数)。 每当unapply返回None某个值时,我们会说使用unapply方法的提取器对象匹配该值。

如果match语句与其任何案例的值不匹配,则会抛出MatchError

答案 1 :(得分:2)

它由unapply方法处理,但不在match处理。由于您的unapply应该返回None,这意味着它不符合case Twice(n)

将其更改为

21 match {
  case Twice(n) => println("this won't happen")
  case x => println("just " + x)
}