Scala - 中缀vs点符号

Kev*_* Li 38 methods scala call infix-notation

一个是另一个最好的做法吗?我一直在阅读Odersky等人 Scala书.似乎infix用于很多Collections API函数,而dot则保留给程序员定义的函数.

mis*_*tor 49

我个人对此没有任何严格的规则,但我倾向于仅使用符号方法名称的中缀符号,以及字母数字符号的点符号.

中缀表示法使得稍后修改代码变得很麻烦.这里有些例子.

想象一下,你有这行代码:

xs filter { f } map { g }
Run Code Online (Sandbox Code Playgroud)

假设在某个后一个时间点你需要添加一个toList结尾.你这么说:

xs filter { f } map { g } toList
Run Code Online (Sandbox Code Playgroud)

这可能会导致分号推断问题.要避免这些问题,您可以在结尾处添加分号,也可以添加新行.在我看来,这两种选择都很难看.为了避免这些废话,我宁愿选择xs.filter(f).map(g).使用这种语法重构总是更容易.

另一个例子:说我的代码中有以下内容:

if(foo contains bar) { ..
Run Code Online (Sandbox Code Playgroud)

说,我需要否定这个条件.如果我修改如下:

if(!foo contains bar) { ..
Run Code Online (Sandbox Code Playgroud)

游民.这被解析为(!foo).contains(bar).不是我们想要的.

或者假设您需要另外添加新条件,并对其进行修改,以便:

if(foo contains bar && cond) { ..
Run Code Online (Sandbox Code Playgroud)

另一个无赖.这被解析为foo.contains(bar.&&(cond)).不是我们想要的,再一次.

当然,你可以添加一堆括号,但与点符号相比,这将是丑陋的,难以阅读/编辑.

现在,我上面说的所有内容也适用于符号方法名称.但是,当使用点语法时,符号方法看起来不自然,所以我更喜欢它们的中缀语法.


上述指南的一个例外:内部DSL.它们通常经过精心设计,以便在按照其文档/示例(通常使用中缀表示法)中规定的方式编写时不会导致解析问题.

  • 同样的逻辑也可以用于支持中缀表示法,因为它提供了一种额外的机制来控制优先级(除了选择运算符).它使得优先级在视觉上更加明显.例如,尝试使用true函数重写您的第一个示例,而不仅仅是提升方法:`(xs filter f map g).toList`仍然比`xs.filter(f).map(g).toList更清晰,更明显. )` (6认同)
  • `someExpression` =>`someExpression.newPart`并没有明显优于`someExpression` =>`(someExpression).newPart`在这两种情况下都必须添加`.newPart`.不可否认,你必须在第二种情况下添加括号,但你可能从一开始就少用它们.稻草人要用"这可能导致分号推断问题"来证明前一种方法的合理性.解释 - 这是添加的后缀调用的症状,而不是原始表达式. (3认同)
  • 括号括起来需要非线性编辑,这是避免中缀表示法的另一个原因.放下牙箍也无济于事. (2认同)
  • 重点放在括号内。当与运算符的相对“强度”以及括号/花括号的使用结合使用时,具有*也*也可以使用中点对点表示法来控制优先级的能力是保持代码整洁的非常强大的工具。 (2认同)

dhg*_*dhg 12

这是个人喜好的问题.您决定使用一种或另一种风格应该基于使您的代码最具可读性的原因.

但请注意,忽略点和括号的能力仅限于某些句法结构,因此有时您只需要回退使用它们.

  • 另请注意,`a.op(b)`比'a op b'长,但比`(a op b)`短.微小的差异,但它可以是"最可读"考虑的一部分. (5认同)