Scala是否有少量的底层语法特征?
Scala是一种有趣的语言,它声称简洁、可伸缩(通过在库中而不是编译器中指定许多特性),并且支持DSL。 在尝试实现这一点时,它有许多运算符和编译器调整(例如,支持中缀运算符,例如:*平展序列) 我发现许多运算符(在“Scala编程”索引中有2½页)和编译器调整令人困惑。公平地说,许多运算符都是从C等人那里借用的传统算术/布尔运算符 有人告诉我,有一些基本的语法规则可以支撑这一点,我认为如果我知道这些规则,就会减少我的认知负荷Scala是否有少量的底层语法特征?,scala,Scala,Scala是一种有趣的语言,它声称简洁、可伸缩(通过在库中而不是编译器中指定许多特性),并且支持DSL。 在尝试实现这一点时,它有许多运算符和编译器调整(例如,支持中缀运算符,例如:*平展序列) 我发现许多运算符(在“Scala编程”索引中有2½页)和编译器调整令人困惑。公平地说,许多运算符都是从C等人那里借用的传统算术/布尔运算符 有人告诉我,有一些基本的语法规则可以支撑这一点,我认为如果我知道这些规则,就会减少我的认知负荷 是否有一些规则(如果有,它们是什么)或者我注定要学习库中的许多“运算
是否有一些规则(如果有,它们是什么)或者我注定要学习库中的许多“运算符”方法和隐式吗?Scala对运算符没有特殊处理 摘自《Scala 2ed编程》一书 任何方法都可以是运算符 在Scala中,运算符并不特殊 语言语法:任何方法都可以是运算符。什么使一种方法成为一种工具 操作员是如何使用它的。当你写“s.indexOf('o')”时,indexOf 他不是接线员。但是当你写“s indexOf'o'”时,indexOf是一个 运算符,因为您在运算符表示法中使用它 我在索引中找不到您所指的2 1/2页 Scala操作符始终可用作某些对象上定义的方法。这也与任何值在scala中都表示为对象这一事实相一致,这与java对原语类型的特殊遗留处理不同 scala底层实现可以利用原语在字节码级别提高性能,但这对最终用户来说是透明的 操作员 所以这里的规则很简单:每个操作符实际上都是在某个类型上定义的方法。运算符中缀符号只是可读性问题,例如
val sum = 1 + 2
读起来比读起来好多了
val sum = 1.+(2)
这种符号也是构建具有“自然感觉”的dsl的基础。测试库清楚地演示了这一点
特殊编译器规则
正如您所说,有有限数量的“编译器调整”,可用于上述目的,以允许更清晰、更易懂的代码
可以找到这些“调整”的相关摘要有两种方法可以理解您关于操作员的问题:
- 唯一可接受的前缀运算符是
,+
,-
代码>和
~
- 任何不带参数的方法都可以用作后缀运算符
- 任何接受一个参数的方法都可以用作中缀运算符。然而,这些运算的优先级取决于特定的规则,大概主要是为了让算术和其他表达式如人们所期望的那样被处理。优先级由操作符/方法名的第一个字符决定,并且与您期望从C或Java获得的内容相匹配
- 除以
结尾的操作符外,所有中缀操作符都是左关联的。典型的例子包括:
和:
+:
++
,-
,**
,+=
,-=
,+=
,-=
等)。解析器组合器有一个更奇特的集合,一些库一开始可能完全无法穿透,因为它们的自定义运算符定义(我想到了sbt或Lift,尽管这只是我个人的观点)
这被认为是潜在问题的根源,《Scala风格指南》必须说明符号方法名称(自定义运算符):
避开!尽管Scala在多大程度上促进了API设计的这一领域,但使用符号名定义方法不应轻率,尤其是当符号本身是非标准的(例如,#>
)时。一般来说,符号方法名称有两种有效的用例:
- 特定于域的语言(例如,
)actor1!Msg
- 逻辑数学运算(例如
或a+b
)c::d
所有信息都可以在和中找到 以下是我对从何处开始的建议:
+
,-
,*
,/
,字母的优先级最低,而奇怪的unicode字母的优先级最高。对于其余部分,我添加了括号,或者只是猜测优先级将按照DSL设计器的意图或类似于Java的方式“工作”x::xs
和xs:::ys
运算符,因为它们非常普遍,并且与右侧关联,因为它们以:
结尾李>