bar*_*oco 6 scala traits case-class
我想创建一个特殊的计算器.我认为这case class对操作来说是一个好主意:
sealed class Expr
case class add(op1:Int, op2:Int) extends Expr
case class sub(op1:Int, op2:Int) extends Expr
case class mul(op1:Int, op2:Int) extends Expr
case class div(op1:Int, op2:Int) extends Expr
case class sqrt(op:Int) extends Expr
case class neg(op:Int) extends Expr
/* ... */
Run Code Online (Sandbox Code Playgroud)
现在我可以使用match-case来解析输入.也许,我也应该使用traits(如:trait Distributivity,trait Commutativity等等),那是更多钞票?这是一个好主意吗?
Lan*_*dei 13
在开始添加不那么明确的附加值的特征之前,您应该掌握正确的基础知识.你现在这样做的方式使这些类不是很有用,至少在构建经典AST(或"解析树")时不是这样.想象一下4*(3 + 5).在使用乘法运算之前,您必须进行评估先添加.这让事情变得复杂.你通常想要的是能够"立刻"编写你的公式,例如Mul(4,Add(3,5)).但是这不会那样,因为你不能将Ints或Doubles放入你自己的类层次结构中.通常的解决方案是Numbers的包装类,比如说"Num".然后我们有:Mul(Num(4),Add(Num(3),Num(5)).这可能看起来很复杂,但现在你有"一下子",你可以做一些事情,比如引入常量和变量,简化(例如Mul(Num(1),x) - > x),派生......
要做到这一点,你需要一些东西
sealed trait Expr {
def eval:Int
}
case class Num(n:Int) extends Expr {
def eval = n
}
case class Neg(e: Expr) extends Expr {
def eval = - e.eval()
}
case class Add(e1: Expr, e2: Expr) extends Expr {
def eval = e1.eval + e2.eval
}
...
Run Code Online (Sandbox Code Playgroud)
现在你可以编写一个解析器,将"4*(3 + 5)"变成Mul(Num(4),Add(Num(3),Num(5)),并通过在该表达式上调用eval来获得结果.
Scala包含一个名为parser combinators的解析库.有关上述代码的示例,请参阅http://jim-mcbeath.blogspot.com/2008/09/scala-parser-combinators.html