2016-02-07 47 views
2

這是一段代碼。當模式匹配時,編譯器不會發出警告。你知道任何解決方法嗎?Scala:對密封特徵進行模式匹配時,編譯器不會發出警告

我想編譯器發出警告,當我忘記案件時模式匹配SimpleExpr.ExprOtherExpr.Expr。這種構造允許我因子是常見的兩種表達式樹(如If

trait Hierarchy { 
    sealed trait Expr 
} 
trait If { 
    this: Hierarchy => 
    case class If(cond: Expr, yes: Expr, no: Expr) extends Expr 
} 
trait Word { 
    this: Hierarchy => 
    case class Word(name: String) extends Expr 
} 

object SimpleExpr extends Hierarchy with If with Word 
//object OtherExpr extends Hierarchy with If with Integer 

object Demo extends App { 
    import SimpleExpr._ 
    def func(expr: Expr) = expr match { 
    case If(cond, yes, no) => cond 
    // compiler should emit warning 
    } 
} 

回答

0

我終於找到了達到理想效果的解決方案:

trait Hierarchy { 
    sealed trait Expr 
    case class Unit() extends Expr 
} 
trait AddIf extends Hierarchy { 
    case class If(cond: Expr) extends Expr 
} 
trait AddWord extends Hierarchy { 
    case class Word(name: String) extends Expr 
} 
trait AddSymb extends Hierarchy { 
    case class Symb(name: String) extends Expr 
} 


object AST1 extends Hierarchy with AddIf 
object AST2 extends Hierarchy with AddSymb with AddIf 


object TestMatch extends App { 
    def match1(e: AST1.Expr) = e match { 
    case AST1.If(cond) => 1 
    } 
    def match2(e: AST2.Expr) = e match { 
    case AST2.If(cond) => 1 
    case AST2.Unit() => 1 
    } 
} 
1

因爲sealed是不可傳遞的,它不是很清楚,我缺乏編譯錯誤是否是錯誤或不節點。

我注意到,向match表達式添加另一個案例會導致編譯器發出「無法訪問的代碼」警告。這裏是我的代碼的修改版本:

#!/usr/bin/env scala 
Demo.main(args) 

sealed trait Hierarchy { 
    sealed trait Expr 
} 
trait If { 
    this: Hierarchy => 
    case class If(cond: Expr, yes: Expr, no: Expr) extends Expr 
} 
trait Word { 
    this: Hierarchy => 
    case class Word(name: String) extends Expr 
} 

object SimpleExpr extends Hierarchy with If with Word 
//object OtherExpr extends Hierarchy with If with Integer 

object Demo extends App { 
    import SimpleExpr._ 
    def func(expr: Expr) = expr match { 
    case If(cond, yes, no) => cond 
    // compiler should emit warning 
    case Word(name) => printf("word[%s]\n",name) 
    } 
    func(Word("yo!")) 
} 

這裏就是我得到的,當我運行它:

warning: unreachable code 
case Word(name) => printf("word[%s]\n",name) 
one warning found 
word[yo!] 

警告不正確,正在執行的unreachable代碼。

case Word行註釋掉,這裏就是我得到:

scala.MatchError: Word(yo!) (of class Main$$anon$1$Word$Word) 
    at Main$$anon$1$Demo$.func(demo.sc:21) 

以下,但是,併發出所需的警告:

#!/usr/bin/env scala 
Demo.main(args) 

sealed trait Expr 
case class Word(name: String) extends Expr 
case class If(cond: Expr, yes: Expr, no: Expr) extends Expr 

trait Hierarchy 
trait IfExpr { 
    this: Hierarchy => 
} 
trait WordExpr { 
    this: Hierarchy => 
} 

object SimpleExpr extends Hierarchy with IfExpr with WordExpr 
//object OtherExpr extends Hierarchy with If with Integer 

object Demo extends App { 
    import SimpleExpr._ 
    def func(expr: Expr) = expr match { 
    case If(cond, yes, no) => cond 
    // compiler should emit warning 
    // case Word(name) => printf("word[%s]\n",name) 
    } 
    // func(Word("yo!")) 
} 

這裏的警告,我得到:

demo.sc:22: warning: match may not be exhaustive. 
It would fail on the following input: Word(_) 
    def func(expr: Expr) = expr match { 
        ^
+0

所以,(確定)你是否同意這是一個錯誤? –

+0

警告似乎是一個錯誤。另一個顯然不是。 – philwalk

+0

我試圖封閉層次結構,但仍然沒有「密封行爲」。你是如何獲得一個的? –

相關問題