在 Scala 中折叠类似的案例陈述

Collapse similar case statements in Scala

是否有一种优雅的方法可以仅使用一个 case 语句来执行类似以下示例的操作?

foobar match {
    case Node(Leaf(key, value), parent, qux) => {
        // Do something with parent & qux
    }
    case Node(parent, Leaf(key, value), qux) => {
        // Do something with parent & qux (code is the same as in the previous case)
    }
    // other cases
}

为了理解这里发生的事情:foobar 是二叉树的一个节点,我匹配节点的一个祖先是 Leaf 节点的情况。这些是使用的类:

abstract class Tree
case class Node(left: Tree, right: Tree, critBit: Int) extends Tree
case class Leaf(key: String, value:String) extends Tree

您可以使用自定义提取器将匹配部分从逻辑部分中抽象出来:

object Leafed {
  def unapply(tree: Tree) = tree match {
    case Node(Leaf(_, _), parent, qux) => Some((parent, qux))
    case Node(parent, Leaf(_, _), qux) => Some((parent, qux))
    case _ => None
  }
}

然后你可以这样定义方法:

def doSomething(tree: Tree): Int = tree match {
  case Leafed(parent, qux) => qux
  case _ => -100
}

你可以这样使用:

scala> val leaf = Leaf("foo", "bar")
leaf: Leaf = Leaf(foo,bar)

scala> doSomething(leaf)
res7: Int = -100

scala> doSomething(Node(leaf, Node(leaf, leaf, 5), 10))
res8: Int = 10

scala> doSomething(Node(Node(leaf, leaf, 5), leaf, 10))
res9: Int = 10

否则你就不走运了——正如上面 Marth 指出的那样,模式替代方案不会在这里帮助你。