Scala - 方法优先级

时间:2011-09-29 12:43:54

标签: scala methods

我是Scala的新手。我想知道是否可以使用方法调用定义一些优先级。例如,如果我有方法调用链:

someObject method1 param1 method2 param2 method3 param3

这可以等同于以下内容:

someObject.method1(param1).method2(param2.method3(param3))

someObject method1 param1 method2 (param2 method3 param3)

所以我希望method3优先于method2 ...

我想这样做的原因是我想开发一个DSL,所以我想避免尽可能多地使用点和圆括号。如果你们为我找到另一种解决方案,请随时告诉我。

2 个答案:

答案 0 :(得分:12)

您必须使用具有特殊运算符字符的方法来影响Tomasz所暗示的优先级。这就是为什么许多Scala DSL大量使用运营商的原因。另外,如果你每天都不使用DSL,那么为什么有些DSL很难阅读呢。

给定只使用字母,下划线和数字的方法 - 你将无法影响事物,这是我在阅读规范后为自己整理的内容:

  • 任何采用单个参数的方法都可以用作中缀运算符:a.m(b)可以写成a m b
  • 任何不需要参数的方法都可以用作后缀运算符:a.m可以写成a m

  • 后缀运算符的优先级低于中缀运算符,因此foo bar baz表示foo.bar(baz),而foo bar baz bam表示(foo.bar(baz)).bam和{{1 }}表示foo bar baz bam bim

因此,根本不知道您的方法签名是什么,以下代码(因为它是所有字母数字):

(foo.bar(baz)).bam(bim)

将被解析为:

someObject method1 param1 method2 param2 method3 param3

如果您将someObject.method1(param1).method2(param2).method3(param3) 重命名为method3|*|或任何有意义的操作符,您可以实现所需目标:

+:+

例如,看看差异:

someObject method1 param1  method2 param2 |*| param3
// same as
someObject.method1(param1).method2(param2.|*|(param3))

答案 1 :(得分:4)

此行为在 Scala语言规范的第6.12.3 Infix Operations章中定义。

简而言之:默认情况下,从左到右调用方法,但有一些例外。这些例外仅用于支持数学运算符优先级。所以当你有两个名为*+的函数时:

a + b * c

这将始终转换为:

a.+(b.*(c))

这里函数的第一个名称控制优先级。但是对于普通功能,您无法控制订单。想一想 - 这实际上会造成破坏性和非常难以维护的代码。

另见(不完全重复?):Operator precedence in Scala