Reputation: 1071
This Scala 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 App {
val x = Twice(5)
println(x)
x match { case Twice(n) => println(n) }
}
prints
10
5
when TwiceTest is run. Question is: x
is an integer and not a function Twice(n)
, so why the pattern matching works?
Upvotes: 0
Views: 62
Reputation: 2337
Patterns as such have nothing to do with objects or encapsulation. The whole semantics of a Pattern is given by the unapply-method of the object of that name. This has to be a function from some type you want to match on to an optional. It matches, if the apply function returns something. You can match on any type and return value you want.
In your case your unapply-method takes an integer and returns an other integer if successful. It does not matter, that the object Twice also has an apply method and it does not matter, where the integer came from.
You can even remove the apply-method an still do this
8 match { case Twice(n) => println(n) }
it will work as well.
The compiler just transforms this into something like
val temp = Twice.unapply(8)
if(temp.isDefined) {
val n = temp.get
println(n)
}
(Probably something more complicated as it has to be more general to support all features of patterns.)
Upvotes: 1
Reputation: 6092
It's because of the pattern matching expression.
Let's take a look at it:
x match {
case Twice(n) => println(n)
}
You are matching using Twice
. In the background, it will call Twice.unapply()
with parameter x
. If the result is Some(foo)
, it will substitute the value of foo
into the value of n
. Otherwise it won't match.
See this for longer explanation.
Upvotes: 2