Scala匹配,从两种不同的模式中解析相同的变量

时间:2013-05-30 09:53:19

标签: scala match

说我有以下

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实际上是一大块代码,不容易封装。

3 个答案:

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

但它不适用于每个参考文献。所以,要小心。