问题
I am kind of confused about extractor and its using. I read Scala document and meet that one
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 App {
val x = Twice(21) // x = 42
x match { case Twice(n) => Console.println(n) } // prints 21
}`
As the above code print out, when we call x match {case Twice(n) ..., it means Twice(n) --> Twice.unapply(n) --> Twice.unapply(42) and get Some(n/2) --> Some(42/2) and plug result into n again, print out 21
If I change "unapply" as follow:
def unapply(z: Int): Option[Int] = if (z%2 == 0) Some(z - 2) else None
What I get from the console is 40
So, do I understand it right?
回答1:
it means
Twice(n)-->Twice.unapply(n)-->Twice.unapply(42)
No, Twice(n) is a pattern (here; it can also be used as an expression, but with a different meaning), and Twice.unapply(n) is an expression. And it's an expression which makes no sense here, because you don't have a value for n yet! Twice.unapply(x) is called instead.
x match { case Twice(n) => ...expression_using_n; ...other cases } is basically the same as
Twice.unapply(x) match {
case Some(n) => ...expression_using_n
case None => x match { ...other cases }
}
Or to remove circularity, since Some itself is an extractor object:
val unapplied = Twice.unapply(x)
if (unapplied.isDefined) {
val n = unapplied.get
...expression_using_n
} else
x match { ...other cases }
来源:https://stackoverflow.com/questions/36859663/scala-extractor-objects-confusion