ps0604
ps0604

Reputation: 1071

Extractor with pattern matching

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

Answers (2)

dth
dth

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

David Frank
David Frank

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

Related Questions