Вопрос

I'm trying out the code at http://www.scala-lang.org/node/112 and I'm getting a match error for something that doesn't look like it should throw one.

This is the original code:

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
}

I just added a few lines to test what happens when I pass an odd number:

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)
}

The case for 21 or any odd number should also be handled by the unapply method in the object as far as I can tell. Can someone explain why this is not the case?

Это было полезно?

Решение

val x = Twice(21)

is the same as

val x = Twice.apply(21)

meaning that x will be equal to 42. The Twice.unapply(42) returns a Some(21), meaning that the case Twice(21) successfully matches the value x == 42.

This is why the first match statement prints out 21.

The Twice.unapply(21) returns None (because y == 21, that is, if y is odd). Whenever an unapply returns None for some value, we say that the extractor object with that unapply method does not match that value.

If a match statement does not match a value to any of its cases, it will throw a MatchError.

Другие советы

It is being handled by your unapply method, but not the match. Since your unapply should return a None, it means that it doesn't meet case Twice(n).

Change it to something like

21 match {
  case Twice(n) => println("this won't happen")
  case x => println("just " + x)
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top