在Scala中的extractors
中,unapply
方法用于模式匹配。该方法是否需要在object
中定义,还是可以在class
中定义?在下面的代码中,我想到了创建一个D的对象(它将具有unapply
方法),但它没有编译。
scala> class D(val i:Int, val j:Int) {
| def unapply(d:D) = Some((d.i, d.j))
| }
defined class D
scala> val d1 = new D(1,2)
d1: D = D@4b22214d
scala> d1 match {
| case new D((i,j)) => println(s"got ${i}, ${j}") //will not compile
| case _ => println("no D")
| }
但是,如果我创建一个伴随对象,模式匹配工作
object D {
def unapply(d:D) = Some((d.i, d.j))
}
defined object D
scala> val d = new D(1,2)
d: D = D@42a7e7e1
scala> d match {
| case D(1,2) =>println("d with 1,2")
| case _ => println("something else")
| }
d with 1,2
答案 0 :(得分:1)
From the specification (section §8.1.8):
提取器模式
提取器模式
x(p1,…,pn)
,其中n ≥ 0
是相同的 句法形式作为构造函数模式。但是,而不是一个案例 class,稳定标识符x 表示具有成员的对象 名为unapply或unapplySeq的方法与模式匹配。
因此,提取器必须是对象定义的一部分。
正如@ sepp2k指出的那样,将x定义为对象定义并不是必需的,x将提供名为unapply的实例方法就足够了。正如他在示例中所示:
class Sub(x: Int) {
def unapply(y: Int) = Some(y-x)
}
object Main extends App {
val Sub23 = new Sub(23)
42 match {
case Sub23(i) => println(i) // Prints 42 - 23
}
}