说我有以下
case class IntWrap(value:Int)
我想从两种情况中提取相同的变量,如下所示:
x match {
case value:Int | IntWrap(value) => dosomethingwith(x)
case _ => ???
}
但我能够做到这一点的唯一方法是:
x match {
case value:Int => dosomethingwith(x)
case IntWrap(value) => dosomethingwith(x)
case _ => ???
}
有没有更好的方法,因为在我的现实生活中,dosomething实际上是一大块代码,不容易封装。
答案 0 :(得分:2)
如果您确实希望使用x
执行某些操作,而不是使用提取的value
执行某些操作,那么以下操作将起作用:
case class IntWrap(value:Int) // extends T
def dosomethingwith(x: Any) = x
val x: Any = IntWrap(101)
x match {
case _: Int | _: IntWrap => dosomethingwith(x)
case _ => ???
}
如果您确实想要使用提取的值,可以将相应的匹配块分解为自己的提取器,并在必要时重用它:
x match {
case Unwrap(value) => dosomethingwith(value)
case _ => ???
}
object Unwrap {
def unapply(x: Any) = x match {
case x: Int => Some((x))
case IntWrap(value) => Some((value))
case _ => None
}
}
答案 1 :(得分:0)
老实说,我没有看到你做事的方式有问题。只要dosomethingwith
是一个单独的函数,我就不会发现重复代码有任何问题。如果您的代码看起来像这样,那么我认为没有必要提出其他解决方案:
def foo(x:Any){
x match {
case value:Int => dosomethingwith(value)
case IntWrap(value) => dosomethingwith(value)
case _ => ???
}
}
def dosomethingwith(x:Int){
//do something complicated here...
}
答案 2 :(得分:0)
我想出了一点点不同,但它可以帮助你避免重复:
case class IntWrap(value: Int)
implicit def intWrapToInt(intWrap: IntWrap) = intWrap.value
def matchInt(x: AnyVal) = x match {
case i: Int => println("int or intWrap")
case _ => println("other")
}
//test
matchInt(IntWrap(12)) //prints int or intWrap
matchInt(12) //prints int or intWrap
matchInt("abc") //prints other
但它不适用于每个参考文献。所以,要小心。