我在Scala中有一个匹配不同case类的函数,但在每次匹配时都执行相同的代码。是否存在“落后”的可能性?还是另一种很好的方法来编写代码,而不需要代码重复,也没有定义函数?
symbol match {
case Times(a,b) => //some code using a and b
case Plus(a,b) => //same code as above
case Div(a,b) => //again same code as above
}
这个问题与“Match "fallthrough": executing same piece of code for more than one case?”非常相似,区别在于我在与案例类匹配时感到沮丧。
答案 0 :(得分:4)
不,Scala禁止使用暴虫,因为它们是其他语言中常见的漏洞来源。你有两个三个可能性:
BinaryOperation
,它使您可以进行更通用的匹配。请注意,由于案例类继承限制,您必须依赖于使用此超类的字段而不是具有超级案例类。答案 1 :(得分:4)
您可以编写自己的提取器,将三种情况组合在一起并将其转换为元组:
object BinOp {
def unapply(op: Op) = op match {
case Times(a, b) => Some(a, b)
case Plus(a, b) => Some(a, b)
case Div(a, b) => Some(a, b)
}
}
symbol match {
case BinOp(a, b) =>
}
答案 2 :(得分:1)
我看到了两个可能解决问题的方法
1)unapply
根据M. Stocker的回答,您可以像这样整理数据:
trait Op
trait BinaryOp extends Op {
def a: Int
def b: Int
}
object BinaryOp {
def unapply(op: Op) = op match {
case x: BinaryOp => Some((x.a, x.b))
case _ => None
}
}
case class Times(a: Int, b: Int) extends BinaryOp
case class Plus(a: Int, b: Int) extends BinaryOp
case class Div(a: Int, b: Int) extends BinaryOp
用法:
symbol match {
case BinaryOp(a, b) => f(a, b)
case _ => //...
}
2)Product
所有案例类都扩展了Product
trait
这允许您进行以下匹配:
symbol match {
case p: Product if p.productArity == 2 => {
val a = p.productElement(0) //this has type Any, so a cast may be necessary
val b = p.productElement(1)
f(a, b)
}
}
第二种情况更通用,但它也是类型不安全的。我推荐第一个解决方案。