在提取器中,unapply方法是否需要在对象中,还是在类中?

时间:2017-11-28 17:14:03

标签: scala

在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

1 个答案:

答案 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
  }
}