在Scala中,我希望能够像这样定义一般类型的抽象语法树节点
sealed abstract class AST[T <: AST[T]] {
def child : List[T] ;
}
case class LeafAST[T <: AST[T]]( x : Int ) extends AST[T] {
def child = Nil
}
case class BranchAST[T <: AST[T]]( left : T, right : T ) extends AST[T] {
def child = left :: right :: Nil
}
现在我可以编写像这样的通用代码
def countLeaves[T <: AST[T]]( x : AST[T]) : Int = x match {
case LeafAST( x ) => 1
case BranchAST( left, right ) => countLeaves[T](left) + countLeaves[T](right)
}
现在我的第一个问题是关键字sealed
似乎没有效果。如果我从匹配表达式中省略一个case,则没有错误。为什么以及如何写出我想要的东西? (我还有其他问题 - 比如如何专注于AST--但是我会在每篇文章中坚持一个问题。)
答案 0 :(得分:0)
没有错误 - 有警告。例如:
scala> :paste
// Entering paste mode (ctrl-D to finish)
sealed abstract class AST[T <: AST[T]] {
def child : List[T] ;
}
case class LeafAST[T <: AST[T]]( x : Int ) extends AST[T] {
def child = Nil
}
case class BranchAST[T <: AST[T]]( left : T, right : T ) extends AST[T] {
def child = left :: right :: Nil
}
// Exiting paste mode, now interpreting.
defined class AST
defined class LeafAST
defined class BranchAST
scala> def countLeaves[T <: AST[T]]( x : AST[T]) : Int = x match {
| case LeafAST( x ) => 1
| }
<console>:10: warning: match is not exhaustive!
missing combination BranchAST
def countLeaves[T <: AST[T]]( x : AST[T]) : Int = x match {
^
countLeaves: [T <: AST[T]](x: AST[T])Int
您可以使用标记-Xfatal-warnings
将其变为错误。