在Scala中匹配的案例类

时间:2012-10-23 21:22:52

标签: scala pattern-matching

我希望这个比较函数匹配两个案例类,但它有点冗长。

Leafs始终处于List中的排序顺序。

  abstract class CodeTree
  case class Fork(left: CodeTree, right: CodeTree, chars: List[Char], weight: Int) extends CodeTree
  case class Leaf(char: Char, weight: Int) extends CodeTree

  def sortCodeTreeFun(x: CodeTree, y: CodeTree) = {
    (x, y) match {
      case (x1: Leaf, y1: Leaf) => true
      case (x1: Fork, y1: Leaf) => x1.weight < y1.weight
      case (x1: Leaf, y1: Fork) => x1.weight < y1.weight
      case (x1: Fork, y1: Fork) => x1.weight < y1.weight
    }
  }

我尝试将CodeTree构造函数修改为:

  abstract class CodeTree(weight: Int)

因此我可以直接比较x和y,但编译器说:

  

“构造函数CodeTree没有足够的参数:(权重:Int)patmat.Huffman.CodeTree”

还有另一种缩短sortCodeTreeFun方法的方法吗?

2 个答案:

答案 0 :(得分:3)

如果要对像代码树这样的元素进行排序,可以使用 Sorting.stableSort

答案 1 :(得分:2)

你可以简单地说:

def sortCodeTreeFun(x: CodeTree, y: CodeTree) = {
  (x, y) match {
    case (_: Leaf, _: Leaf)           => true
    case (x1: CodeTree, y1: CodeTree) => x1.weight < y1.weight
  }
}

将抽象类CodeTree定义为

abstract class CodeTree {
  def weight: Int
}

错误的原因是当你扩展一个带参数的类时,你需要提供参数。

abstract class CodeTree(weight: Int)

您需要将其扩展为

case class Fork(left: CodeTree, right: CodeTree, chars: List[Char], weight: Int) extends CodeTree(weight)

这就是你得到的错误:

"not enough arguments for constructor CodeTree: (weight: Int)"

这是因为在扩展CodeTree时你没有提供所需的参数weight

这种方法的问题是,权重不是CodeTree的成员,因此无法从CodeTree类型的实例访问。也就是说,如果你这样做了:

 scala> Fork(...).asInstanceOf[CodeTree].weight
 <console>:11: error: value weight is not a member of CodeTree

因此,在您的模式匹配中,您将无法执行x1.weight,因为x1的类型是CodeTreeCodeTree没有weight