Reputation: 1935
Say I have the following
case class IntWrap(value:Int)
I would like to extract the same variable from two cases as follows:
x match {
case value:Int | IntWrap(value) => dosomethingwith(x)
case _ => ???
}
but the only way I have been able to do this is as:
x match {
case value:Int => dosomethingwith(x)
case IntWrap(value) => dosomethingwith(x)
case _ => ???
}
Is there a better way, as in my real life case dosomething is actually a large block of code which is not so easy to encapsulate.
Upvotes: 1
Views: 577
Reputation: 3573
I came up with sth a little bit different, but it may help you avoid duplicates:
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
It won't work for every reference, though. So, be careful.
Upvotes: 0
Reputation: 12852
If it is really the case that you want to do something with x
, not with the extracted value
, then the following would work:
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 _ => ???
}
If you actually want to work with the extracted value, you could factor out the corresponding match block into its own extractor and reuse that wherever necessary:
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
}
}
Upvotes: 2
Reputation: 35463
I honestly don't see an issue with the way you are doing things. As long as dosomethingwith
is a separate function then I don't see any issues with duplicate code. If your code looked like this then I don't see any need to come up with other solutions:
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...
}
Upvotes: 0