2017-02-21 137 views
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 

,然后使用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可以有NoneSome作为值。在Option[Node]的情况下,它可以是Some(LeafNode)Some(BranchNode)。我还忽略了什么其他案例?

回答

5

由于您的性状不是sealed,它可以在不同包装中进行扩展。 IntelliJ警告你未来的可能性是,任何人扩展这种特性并忘记实施额外的case可能会导致MatchError。如果你想限制它的扩展,使用方法:

sealed trait Node 
3

肯定它的编译器警告,请参阅下面我打破你的代码,通过传递printTree(Option(IWillBreakYou(2)))

match error

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