Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 匹配“;故障排除”;:为多个case类执行同一段代码?_Scala - Fatal编程技术网

Scala 匹配“;故障排除”;:为多个case类执行同一段代码?

Scala 匹配“;故障排除”;:为多个case类执行同一段代码?,scala,Scala,我在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) => //agai

我在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
}

这也是一个非常类似的问题“”,不同的是我在匹配case类时强调了这一点。

不,在Scala中禁止使用falltrough,因为它们是其他语言中常见的错误源。您有两种或三种可能性:

  • 计算出函数中所有相同的项
  • 尝试使用不太特定的匹配,即使用通配符。在您的示例中,这可能还意味着引入一个超类
    二进制操作
    ,它为您提供了更通用的匹配。注意,由于case类继承限制,您必须依赖于使用这个超类的字段,而不是使用一个超级case类
  • 遵循Mirko Stocker关于编写特定提取器的建议

您可以编写自己的提取器,将这三种情况组合起来,并将它们转换为一个元组:

  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) => 
  }

我认为你的问题有两种可能的解决办法

1)
取消应用

根据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)
产品

所有案例类都扩展了
产品

这允许您进行以下匹配:

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)
  }
}

第二种情况更一般,但它也是类型不安全的。我推荐第一种解决方案。

命名函数?先提取到Tuple2,然后处理?是的,这是可能的。但我在寻找另一种方式。为函数命名很难;)谢谢,谢谢你指出了不同的可能性!谢谢你,伙计!这正是我要找的。我的代码现在好多了。我忘了在我的问题中提到Times、Plus等在库中,我不能编辑它们。无论如何,谢谢你写的好文章。