在scala中管理自定义表达式的最佳方法

在scala中管理自定义表达式的最佳方法,scala,null,operators,overloading,abstract-syntax-tree,Scala,Null,Operators,Overloading,Abstract Syntax Tree,我正在为自定义非类型化表达式创建一个新的抽象语法树,我想重新定义其中的==运算符,如下所示: trait Expression { def ==(other: Expression): Expression = Equality(this, other) def !=(other: Expression): Expression = Inequality(this, other) } case class Equality(e1: Expression, e2: Expression)

我正在为自定义非类型化表达式创建一个新的抽象语法树,我想重新定义其中的==运算符,如下所示:

trait Expression {
  def ==(other: Expression): Expression = Equality(this, other)
  def !=(other: Expression): Expression = Inequality(this, other)
}
case class Equality(e1: Expression, e2: Expression) extends Expression
case class Inequality(e1: Expression, e2: Expression) extends Expression
case class Integer(e: Int) extends Expression
case class Boolean(e: Boolean) extends Expression
我现在遇到的唯一问题是测试这种表达式的空值。 例如,当我写这篇文章时:

val formula: Expression = someFunctionReturingAnExpression
if(formula != null) {
  ... use the formula.
}
它抛出一个
java.lang.NullPointerException
,因为它正在应用方法
=
公式


关于如何实现
的可表达性,有什么好主意吗=
和空检查?

您正在重载
==
=操作员在那里。您展示的代码并没有真正为我编译,因为它不能在if子句中将表达式强制转换为Boolean。因此,您可以在null上使用向下转换,以便编译器使用
Any
中的
=
运算符:

if (formula != null.asInstanceOf[Any]) {
    println("hello")
}
上面的表达对我很有用

您还可以使用
AnyRef
中的引用相等运算符:

if (formula eq null) {
    println("hello")
}

if (formula ne null) {
    println("!hello")
}

我还订阅了ziggystar和Dylan的评论-你应该使用不同的运营商名称(
==
,例如),不要使用
null
-使用
选项

我认为你应该为你的DSL寻找另一个平等的符号,比如
~
~。旁注:如果可以,请不要使用null。如果有一个类型为
T
的值可能为null,请改用
选项[T]
。在上面的旁注中添加一条:使您的基本特征扩展
NotNull
,以获得更多的保证,确保它不会被其他人错误地使用:
特征表达式扩展NotNull
。现在,如果您尝试
val-formula:Expression=null
,您将得到一个编译错误。