我有来自库类的案例,我想覆盖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
。这有什么问题?
答案 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中的模式匹配会获取您的对象并对其应用多个unapply
和unapplySeq
方法,直到获得Some
的值与模式中指定的值匹配为止。
如果MyClassA(1)
,则a
与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 _ => ???
}
答案 1 :(得分:1)
我会抛弃过载的unapply,只需使用以下内容进行匹配:
a match {
case MyClass(x, _, _, _) => x // Result is: 1
case _ => "no"
}
编辑:
如果你真的想避免额外的下划线,我想你需要看一下像:
a match {
case x:MyClass => x.a
case _ => "no"
}