1

说我有以下

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 _ => ???
}

有没有更好的方法,因为在我的现实生活中,dsomething 实际上是一大块不容易封装的代码。

4

3 回答 3

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
  }
}
于 2013-05-30T10:17:19.927 回答
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...
}
于 2013-05-30T10:18:08.507 回答
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

但是,它不适用于所有参考。所以,要小心。

于 2013-05-30T10:42:07.260 回答