Scala是否有少量的底层语法特征?

Scala是否有少量的底层语法特征?,scala,Scala,Scala是一种有趣的语言,它声称简洁、可伸缩(通过在库中而不是编译器中指定许多特性),并且支持DSL。 在尝试实现这一点时,它有许多运算符和编译器调整(例如,支持中缀运算符,例如:*平展序列) 我发现许多运算符(在“Scala编程”索引中有2½页)和编译器调整令人困惑。公平地说,许多运算符都是从C等人那里借用的传统算术/布尔运算符 有人告诉我,有一些基本的语法规则可以支撑这一点,我认为如果我知道这些规则,就会减少我的认知负荷 是否有一些规则(如果有,它们是什么)或者我注定要学习库中的许多“运算

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的基础。测试库清楚地演示了这一点

特殊编译器规则

正如您所说,有有限数量的“编译器调整”,可用于上述目的,以允许更清晰、更易懂的代码


可以找到这些“调整”的相关摘要

有两种方法可以理解您关于操作员的问题:

  • 什么是控制Scala编译器如何处理运算符的规则?(语文规则)
  • 控制如何在库中定义运算符的规则是什么?(操作员定义)
  • 语言规则 确实有规则。我会让你决定你是否认为它们“很少”。与Scala中的大多数内容一样,您可以在第6.12节中找到它们

    最重要的是:

    • 唯一可接受的前缀运算符是
      +
      -
      ~

    • 任何不带参数的方法都可以用作后缀运算符

    • 任何接受一个参数的方法都可以用作中缀运算符。然而,这些运算的优先级取决于特定的规则,大概主要是为了让算术和其他表达式如人们所期望的那样被处理。优先级由操作符/方法名的第一个字符决定,并且与您期望从C或Java获得的内容相匹配

    • 除以
      结尾的操作符外,所有中缀操作符都是左关联的。典型的例子包括
      +:

    基本上有四条规则。我鼓励您阅读规范以获得更多的洞察力

    运算符定义 运算符定义的选择由库设计者决定。例如,Scala集合库使用了一组相对较小且一致的运算符(
    ++
    -
    **
    +=
    -=
    +=
    -=
    等)。解析器组合器有一个更奇特的集合,一些库一开始可能完全无法穿透,因为它们的自定义运算符定义(我想到了sbt或Lift,尽管这只是我个人的观点)

    这被认为是潜在问题的根源,《Scala风格指南》必须说明符号方法名称(自定义运算符):

    避开!尽管Scala在多大程度上促进了API设计的这一领域,但使用符号名定义方法不应轻率,尤其是当符号本身是非标准的(例如,
    #>
    )时。一般来说,符号方法名称有两种有效的用例:

    • 特定于域的语言(例如,
      actor1!Msg
    • 逻辑数学运算(例如
      a+b
      c::d

    所有信息都可以在和中找到

    以下是我对从何处开始的建议:

  • 了解如何将标识符序列解析为操作数和运算符。请参阅我关于此主题的答案
  • 记住足够多的运算符优先级。就我个人而言,我只记得算术
    +
    -
    *
    /
    ,字母的优先级最低,而奇怪的unicode字母的优先级最高。对于其余部分,我添加了括号,或者只是猜测优先级将按照DSL设计器的意图或类似于Java的方式“工作”
  • 学习列表的
    x::xs
    xs:::ys
    运算符,因为它们非常普遍,并且与右侧关联,因为它们以
    结尾
  • 或者,如果您感到好奇,可以粗略地查看一下规范的第6.12节前缀、中缀和后缀操作,以便