Scala 在匹配模式時(shí),按照模式定義的順序依次檢查,因此越特定的規(guī)則越要先定義,而通用的規(guī)則后定義。比如我們修改之前的
def simplifyTop(expr :Expr) :Expr = expr match {
case UnOp("-",UnOp("-",e))=>e
case BinOp("+",e,Number(0))=>e
case BinOp("*",e,Number(1))=>e
case _ => expr
}
使它可以簡化任意層次的表達(dá)式,我們需要添加兩個(gè)通用的規(guī)則,定義如下:
def simplifyAll(expr :Expr) :Expr = expr match {
case UnOp("-",UnOp("-",e))=>e
case BinOp("+",e,Number(0))=>e
case BinOp("*",e,Number(1))=>e
case UnOp(op,e) => UnOp(op,simplifyAll(e))
case BinOp(op,l,r)=>BinOp(op,simplifyAll(l),simplifyAll(r))
case _ => expr
}
simplifyAll 規(guī)則 1 是規(guī)則 4 的特例,而規(guī)則 2,3 是規(guī)則 5 的特例,因此 1,2,3 需要定義在 4,5 之前,而最后的缺省規(guī)則需要放在最后,如果順序反了,比如把通用的規(guī)則放在特例之前,編譯器會(huì)給出警告,因?yàn)楫?dāng) Scala 做匹配時(shí),按照規(guī)則定義的順序,首先匹配通用規(guī)則,規(guī)則匹配成功,后面的特例沒有機(jī)會(huì)匹配,比如:
def simplifyBad(expr:Expr):Expr = expr match{
case UnOp(op,e) => UnOp(op,simplifyBad(e))
case UnOp("-",UnOp("-",e))=>e
}
<console>:12: warning: unreachable code
case UnOp("-",UnOp("-",e))=>e
^
simplifyBad: (expr: Expr)Expr