提取器与模式匹配

时间:2016-02-07 22:09:39

标签: scala

此Scala代码

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

打印

10
5

运行TwiceTest时。问题是:x是一个整数而不是函数Twice(n),那么为什么模式匹配有效呢?

2 个答案:

答案 0 :(得分:2)

这是因为模式匹配表达式。

让我们来看看它:

x match {
  case Twice(n) => println(n)
}

您正在使用Twice进行匹配。在后台,它会使用参数Twice.unapply()调用x。如果结果为Some(foo),则会将foo的值替换为n的值。否则它就不会匹配。

有关详细说明,请参阅this

答案 1 :(得分:1)

这样的模式与对象或封装无关。 Pattern的整个语义由该名称对象的unapply-method给出。这必须是您想要匹配的某种类型的函数。如果apply函数返回某些内容,则匹配。您可以匹配任何类型和返回值。

在您的情况下,unapply-method接受一个整数,如果成功则返回另一个整数。没关系,对象Twice也有一个apply方法,并且无关紧要,整数来自哪里。

您甚至可以删除apply-method仍然执行此操作

8 match { case Twice(n) => println(n) }

它也会起作用。

编译器只是将其转换为类似

的内容
val temp = Twice.unapply(8)
if(temp.isDefined) {
  val n = temp.get
  println(n)
}

(可能更复杂,因为它必须更加通用以支持模式的所有功能。)