覆盖unapply方法

时间:2013-09-17 11:36:55

标签: scala

我有来自库类的案例,我想覆盖unapply方法以减少参数数量我需要传递来进行模式匹配反对。我这样做:

object ws1 {
  // a library class
  case class MyClass(a: Int, b: String, c: String, d: Double /* and many more ones*/)

  // my object I created to override unapply of class MyClass
  object MyClass {
    def unapply(x: Int) = Some(x)
  }

  val a = new MyClass(1, "2", "3", 55.0 /* and many more ones*/)
  a match {
    case MyClass(x /*only the first one is vital*/) => x  // java.io.Serializable = (1,2,3,55.0)
    case _ => "no"
  }
}

但我希望它只返回1。这有什么问题?

2 个答案:

答案 0 :(得分:6)

case class MyClass(a: Int, b: String, c: String, d: Double /* and many more ones*/)
object MyClassA {
   def unapply(x: MyClass) = Some(x.a)
}

val a = new MyClass(1, "2", "3", 55.0 /* and many more ones*/)

a match {
    case MyClassA(2) => ??? // does not match
    case MyClassA(1) => a   // matches
    case _ => ??? 
}

您无法在unapply对象中定义自定义MyClass方法,因为它必须采用MyClass参数,并且已经有一个这样的方法 - 一个自动生成案例类。因此,您必须在另一个对象中定义它(在这种情况下为MyClassA)。

Scala中的模式匹配会获取您的对象并对其应用多个unapplyunapplySeq方法,直到获得Some的值与模式中指定的值匹配为止。
如果MyClassA(1),则aMyClassA.unapply(a) == Some(1)匹配。

注意:如果我写了case m @ MyClassA(1) =>,那么m变量的类型为MyClass

编辑:

a match {
    case MyClassA(x) => x  // x is an Int, equal to a.a
    case _ => ??? 
}

答案 1 :(得分:1)

我会抛弃过载的unapply,只需使用以下内容进行匹配:

a match {
  case MyClass(x, _, _, _) => x  // Result is: 1
  case _ => "no"
}

编辑:

如果你真的想避免额外的下划线,我想你需要看一下像:

a match {
  case x:MyClass => x.a
  case _ => "no"
}