我正在尝试使用以下定义定义二叉树:
trait Node {
val label: Int
}
case class BranchNode(override val label: Int, left: Option[Node], right: Option[Node]) extends Node
case class LeafNode(override val label: Int) extends Node
然后使用Scala的模式匹配定义一个简单的printTree
方法,如下所示:
def printTree(aTree: Option[Node]): Unit = aTree match {
case None => print(".")
case Some(LeafNode(label)) => print(label)
case Some(BranchNode(label, left, right)) => "{" + printTree(left) + label + printTree(right) + "}"
}
Intellij IDE警告我,这场比赛可能并非详尽无遗。 Option
可以包含None
或Some
个值。如果是Option[Node]
,则可以是Some(LeafNode)
或Some(BranchNode)
。我还有什么其他情况可以忽略?
答案 0 :(得分:6)
由于您的特征不是sealed
,因此它可以在不同的包中进行扩展。 IntelliJ警告您,未来有可能延长此特性而忘记实施其他case
的人可能会导致MatchError
。如果要限制其扩展名,请使用:
sealed trait Node
答案 1 :(得分:3)
肯定是编译器警告,请参阅下面我通过传递printTree(Option(IWillBreakYou(2)))
trait Node {
val label: Int
}
case class BranchNode(override val label: Int, left: Option[Node], right: Option[Node]) extends Node
case class LeafNode(override val label: Int) extends Node
case class IWillBreakYou(override val label: Int) extends Node
def printTree(aTree: Option[Node]): Unit = aTree match {
case None => print(".")
case Some(LeafNode(label)) => print(label)
case Some(BranchNode(label, left, right)) => "{" + printTree(left) + label + printTree(right) + "}"
}
val leftNode = Option(LeafNode(2))
val rightNode = Option(LeafNode(3))
printTree(Option(BranchNode(1, leftNode, rightNode)))
printTree(Option(IWillBreakYou(2))) //this will fail
原因是你正在使用Option[Node]
并且任何人都可以延长Node
(在包内/外,除非受到保护),你在比赛中没有考虑。
因此,添加故障安全匹配case _
将解决未来的错误。
def printTree(aTree: Option[Node]): Unit = aTree match {
case None => print(".")
case Some(LeafNode(label)) => print(label)
case Some(BranchNode(label, left, right)) => "{" + printTree(left) + label + printTree(right) + "}"
case _ => println("do nothing")
}