最终==和!=的解决方法scala DSL中的(等于和不等于)方法

最终==和!=的解决方法scala DSL中的(等于和不等于)方法,scala,equals,dsl,Scala,Equals,Dsl,因此,我正在包装Mechanical Turk API,您需要指定资格要求,例如: Worker_Locale == "US" Worker_PercentAssignmentsApproved > 95 ... 在我的代码中,我希望允许使用上述语法,并将其转换为如下内容: QualificationRequirement("00000000000000000071", "LocaleValue.Country", "EqualTo", "US") QualificationRequir

因此,我正在包装Mechanical Turk API,您需要指定资格要求,例如:

Worker_Locale == "US"
Worker_PercentAssignmentsApproved > 95
...
在我的代码中,我希望允许使用上述语法,并将其转换为如下内容:

QualificationRequirement("00000000000000000071", "LocaleValue.Country", "EqualTo", "US")
QualificationRequirement("000000000000000000L0", "IntegerValue", "GreaterThan", 95)
我可以通过声明以下对象来实现我想要的大部分功能:

object Worker_PercentAssignmentsApproved {
  def >(x: Int) = {
    QualificationRequirement("000000000000000000L0", "IntegerValue", "GreaterThan", x)
  }
}
但是我不能对“==”(等于)或“!=”(不等于)方法做同样的事情,因为它们在AnyRef中声明为final。是否有标准的解决方法?也许我应该用“==”和“!==”来代替

(我想一个好的答案可能是总结几个不同的scala DSL是如何选择解决这个问题的,然后我就可以做大多数人做的任何事情。)

编辑:请注意,我并没有试图实际执行相等比较。相反,我试图观察用户在scala代码中指示的比较运算符,保存该比较的基于对象的描述,并将该描述提供给服务器。具体来说,下面是scala代码:

Worker_Locale == "US"
将导致以下参数添加到我的请求中:

&QualificationRequirement.1.QualificationTypeId=000000000000000000L0
&QualificationRequirement.1.Comparator=EqualTo
&QualificationRequirement.1.LocaleValue.Country=US

因此,我不能重写
equals
,因为它返回一个
布尔值,我需要返回一个表示所有这些参数的结构。

如果您查看
=
的定义=
在scala参考文件(§12.1)中,您会发现它们是根据
eq
equals
定义的

eq
是参考等式,也是
final
(在这种情况下,它仅用于检查
null
),但您应该能够覆盖
equals

请注意,您可能还需要编写
hashCode
方法以确保
∀ o1,o2带有
o1。等于(o2)
⇒ <代码>(o1.hashCode.equals(o2.hashCode))


但是,如果您的DSL需要除布尔型之外的其他返回类型,或者通常需要更大的灵活性,那么您应该使用
===
,例如,在中已经做过这样的操作。

这里有一个关于各种DSL在这类事情上使用的小调查

在Javascript表达式中使用
=

JsIf(ValById("username") === value.toLowerCase, ...)
authors.where(a=> a.lastName === "Pouchkine")
person.firstName $eq "Ben"
'Z === 'A
对SQL表达式使用
=

JsIf(ValById("username") === value.toLowerCase, ...)
authors.where(a=> a.lastName === "Pouchkine")
person.firstName $eq "Ben"
'Z === 'A
对SQL表达式使用
$eq

JsIf(ValById("username") === value.toLowerCase, ...)
authors.where(a=> a.lastName === "Pouchkine")
person.firstName $eq "Ben"
'Z === 'A
对序言表达式使用
==

JsIf(ValById("username") === value.toLowerCase, ...)
authors.where(a=> a.lastName === "Pouchkine")
person.firstName $eq "Ben"
'Z === 'A
使用
==
获取
选项而不是
布尔值

assert("hello" === "world")

所以我认为大家的共识主要是使用
===

我一直在考虑一个类似的问题。我在考虑创建一个DSL来编写特定领域的公式。问题是,用户可能也想进行字符串操作,而最终得到的表达式类似于

"some string" + <someDslConstruct>
“一些字符串”+
不管你做什么都会让莱克斯觉得

stringToLiteralString("some string" + <someDslConstruct>)
stringToLiteralString(“某些字符串”+)

我认为唯一可能走出这个陷阱的方法是尝试使用。在您的示例中,也许可以使用一个宏来包装scala表达式并将原始AST转换为查询?对任意表达式执行此操作是不可行的,但如果您的域受到足够的约束,它可能是一个可行的替代解决方案。

我编辑了此问题,以便更清楚地表明,
等于
在这里确实不是一个可行的选项,因为它返回
布尔值。谢谢你链接到Squiryl!