Scala是否具有少量的底层语法功能?

时间:2012-11-10 11:08:17

标签: scala

Scala是一种有趣的语言,声称简洁,可扩展(通过在库中指定许多功能而不是编译器),并支持DSL。 在尝试实现这一目标时,它有许多运算符和编译器调整(例如,支持中缀运算符,例如:_ *以展平序列)。

我发现很多运算符('Scala编程'索引中的2½页)和编译器调整令人困惑。公平地说,许多运算符是从C等人那里借来的传统算术/布尔运算符。

我被告知支撑这个有一些基本的句法规则,我认为如果我知道这些会减少我的认知负担。

是否有一些规则(如果是的话,它们是什么)或者我注定要学习图书馆中的许多“操作员”方法和含义?

3 个答案:

答案 0 :(得分:7)

有两种方法可以理解有关运营商的问题:

  1. 有哪些规则可以控制Scala编译器如何处理运算符? (语言规则)
  2. 管理运营商在图书馆中的定义方式有哪些规则? (运营商定义)
  3. 语言规则

    确实有规则。我会让你确定你是否认为他们中有“少数”。与Scala一样,您可以在Language Reference第6.12节中找到它们。

    最重要的一点:

    • 唯一接受的前缀运算符为+-!~

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

    • 任何带有一个参数的方法都可以用作 infix 运算符。然而,这些操作的优先级受特定规则的约束,可能大部分是因为算术和其他表达式被视为人们期望的。优先级由运算符/方法名称的第一个字符确定,并与您对C或Java的期望值相匹配。

    • 所有中缀运算符都是左关联运算符,但以:结尾的运算符除外。典型示例包括::+:

    基本上是四条规则。我鼓励您阅读规范以获得更多见解。

    运营商定义

    操作员定义的选择取决于库设计者。例如,Scala集合库使用一组相对较小且一致的运算符(++--**+=-=,{{ 1}},++=--=等)。 Parser组合器带有更具异国情调的组合,有些库最初可能是完全无法穿透的,因为他们的自定义操作员定义(想到sbt或Lift,虽然这只是我个人的意见)。

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

      

    避免!尽管Scala在多大程度上促进了API设计的这一领域,但不应轻率地定义具有符号名称的方法,尤其是当符号本身是非标准的时(例如,+:)。作为一般规则,符号方法名称有两个有效的用例:

         
        
    • 特定于域的语言(例如>>#>>
    •   
    • 逻辑数学运算(例如actor1 ! Msga + b
    •   

答案 1 :(得分:1)

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

特殊编译器规则

正如你所说,有一些有限的“编译器调整”可用于上述目的,即允许更清晰,更易理解的代码。

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

答案 2 :(得分:1)

所有信息均可在stackoverflowspec中找到。

以下是我的建议:

  1. 了解如何将标识符序列解析为操作数和运算符。请参阅我对此主题的回答When to use parenthesis in Scala infix notation
  2. 请记住运算符优先级list。就个人而言,我只记得算术+-*/的那些,字母具有最低优先级,而奇怪的unicode具有最高优先级。对于其余部分,我添加括号或者只是猜测优先级将像DSL设计者在Java中所期望的那样“解决”。
  3. 了解列表的x :: xsxs ::: ys运算符,因为它们非常流行且与右侧相关联,因为它们以:结尾。
  4. 或者,如果您感到好奇,请粗略地查看规范的 6.12前缀,中缀和后缀操作部分,这样您就可以在大脑的某个角落知道有具有=和前缀运算符的运算符的细节。
  5. 最后,最后一句忠告。不要试图学习所有操作员,不要认为你应该知道所有操作员的意思,以有效地使用该语言。这是除非您通过阅读和记住完整的API学习了其他语言。