Scala需要这个演员吗?

时间:2013-11-11 01:19:33

标签: scala casting

假设我有一个带有子类abstract BinaryTreeNode的简单Leaf,我想写一个产生List[Leaf]的函数。

def getLeaves(tree: BinaryTree): List[Leaf] =
    tree match {
      case Leaf(v) => List(tree.asInstanceOf[Leaf])
      case Node(left, right) => getLeaves(left) ++ getLeaves(right)
    }

有没有办法避免在asInstanceOf[Leaf] 案例中明确Leaf强制转换?如果我把它遗漏,我得到一个诊断说法:发现:BinaryTree;需要Leaf。

3 个答案:

答案 0 :(得分:8)

我在其他地方看过这个结构。它似乎可以完成这项工作。

def getLeaves(tree: BinaryTree): List[Leaf] =
    tree match {
      case leaf: Leaf => List(leaf)
      case Node(left, right) => getLeaves(left) ++ getLeaves(right)
    }

答案 1 :(得分:3)

试试这种方式

def getLeaves(tree: BinaryTree): List[Leaf] =
    tree match {
      case x@Leaf(v) => List(x)
      case Node(left, right) => getLeaves(left) ++ getLeaves(right)
    }

另请注意,由于您要在每个节点中创建新列表,因此您的实施在性能方面表现不佳。

可以通过这种方式修复

def genLeaves(tree:BinaryTree) = {
  def getLeaves0(tree: BinaryTree, acc:List[Leaf]): List[Leaf] =
    tree match {
      case x@Leaf(v) => x::acc
      case Node(left, right) => {
         val leftLeaves = getLeaves(left, acc)
         getLeaves(right, leftLeaves)
         }
    }
  getLeaves0(tree).reverse
}

下面'您将重复使用已收集的所有项目,并且您在遍历期间只会分配一个列表。您在遍历它时会收集元素,因此您将以相反的顺序结束Leaf(List作为LIFO),因此要按照您访问它的方式获取元素,我们需要反转结果列表。

答案 2 :(得分:1)

您可以利用已经解构treeLeaf(v)的事实,并重建树叶:

def getLeaves(tree: BinaryTree): List[Leaf] =
    tree match {
        case Leaf(v) => List(Leav(v))
        case Node(left, right) => getLeaves(left) ++ getLeaves(right)
    }