2017-02-21 141 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") 
}