7

我有一个来自库类的案例,我想重写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。这有什么问题?

4

2 回答 2

8
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)匹配aif MyClassA.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 _ => ??? 
}
于 2013-09-17T12:38:02.443 回答
1

我会放弃重载的 unapply 并使用以下内容进行匹配:

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

编辑 :

如果您真的想避免使用额外的下划线,我认为您需要查看以下内容:

a match {
  case x:MyClass => x.a
  case _ => "no"
}
于 2013-09-17T11:50:50.710 回答