2

我正在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 方法处理。有人可以解释为什么不是这样吗?

4

2 回答 2

6
val x = Twice(21)

是相同的

val x = Twice.apply(21)

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

这就是match打印出第一条语句的原因21

Twice.unapply(21)返回None(因为y == 21,即如果是y奇数)。每当 aunapply返回None某个值时,我们就说具有该方法的提取器对象与该值unapply匹配

如果一个match语句的值与它的任何情况都不匹配,它将抛出一个MatchError.

于 2012-06-25T14:06:53.383 回答
2

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

将其更改为类似

21 match {
  case Twice(n) => println("this won't happen")
  case x => println("just " + x)
}
于 2012-06-25T14:05:29.943 回答