我是Scala的新手.我想知道是否可以使用方法调用定义一些优先级.例如,如果我有方法调用链:
someObject method1 param1 method2 param2 method3 param3
Run Code Online (Sandbox Code Playgroud)
这可以等同于以下内容:
someObject.method1(param1).method2(param2.method3(param3))
Run Code Online (Sandbox Code Playgroud)
要么
someObject method1 param1 method2 (param2 method3 param3)
Run Code Online (Sandbox Code Playgroud)
所以我希望method3优先于method2 ...
我想这样做的原因是我想开发一个DSL,所以我想避免尽可能多地使用点和圆括号.如果你们为我找到另一种解决方案,请随时告诉我.
huy*_*hjl 12
您必须使用具有特殊运算符字符的方法来影响Tomasz所暗示的优先级.这就是为什么许多Scala DSL大量使用运营商的原因.另外,如果你每天不使用它们,一些DSL很难读懂.
给定只使用字母,下划线和数字的方法 - 你将无法影响事物,这是我在阅读规范后为自己整理的内容:
a.m(b)
可以编写a m b
.任何不需要参数的方法都可以用作后缀运算符:a.m
可以编写a m
.
Postfix的运营商比中缀运算符的优先级低,因此foo bar baz
意味着foo.bar(baz)
尽管foo bar baz bam
手段(foo.bar(baz)).bam
和foo bar baz bam bim
方式(foo.bar(baz)).bam(bim)
.
因此,根本不知道您的方法签名是什么,以下代码(因为它是所有字母数字):
someObject method1 param1 method2 param2 method3 param3
Run Code Online (Sandbox Code Playgroud)
将被解析为:
someObject.method1(param1).method2(param2).method3(param3)
Run Code Online (Sandbox Code Playgroud)
如果您重命名method3
为|*|
或者+:+
任何有意义的操作符,您可以实现您想要的:
someObject method1 param1 method2 param2 |*| param3
// same as
someObject.method1(param1).method2(param2.|*|(param3))
Run Code Online (Sandbox Code Playgroud)
例如,看看差异:
implicit def pimp(s:String) = new {
def |*|(t:String) = t + s
def switch(t:String) = t + s
}
scala> "someObject" concat "param1" concat "param2" |*| "param3"
res2: java.lang.String = someObjectparam1param3param2
scala> "someObject" concat "param1" concat "param2" switch "param3"
res3: java.lang.String = param3someObjectparam1param2
Run Code Online (Sandbox Code Playgroud)
此行为在Scala 语言规范的第 6.12.3 中缀操作一章中定义。
简而言之:默认情况下,方法是从左到右调用的,但有一些例外。引入这些例外只是为了支持数学运算符优先级。因此,当您有两个名为*
和 的函数时+
:
a + b * c
Run Code Online (Sandbox Code Playgroud)
这将始终被翻译为:
a.+(b.*(c))
Run Code Online (Sandbox Code Playgroud)
这里函数的名字控制优先级。但是对于普通函数,您无法控制顺序。想想看 - 这实际上会造成严重破坏并且代码非常难以维护。
另请参阅(不太重复?):Scala 中的运算符优先级。
归档时间: |
|
查看次数: |
1594 次 |
最近记录: |