此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)
,那么为什么模式匹配有效呢?
答案 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)
}
(可能更复杂,因为它必须更加通用以支持模式的所有功能。)