是否有一个最佳实践?我一直在阅读Odersky 等人的Scala 书。似乎中缀用于许多集合 API 函数,而 dot 保留用于程序员定义的函数。
4 回答
我个人对此没有任何硬性规定,但我倾向于仅对符号方法名称使用中缀表示法,对字母数字方法名称使用点表示法。
中缀表示法使得以后修改代码很麻烦。这里有些例子。
想象一下你有这行代码:
xs filter { f } map { g }
假设在稍后的某个时间点您需要toList
在末尾添加一个。你这样说:
xs filter { f } map { g } toList
这可能会导致分号推断问题。为避免这些问题,您可以在末尾添加分号,或者换行。在我看来,这两种选择都很丑陋。为了避免所有这些废话,我更喜欢使用xs.filter(f).map(g)
. 使用这种语法重构总是更容易。
另一个例子:假设我的代码中有以下内容:
if(foo contains bar) { ..
说,我需要否定条件。如果我修改如下:
if(!foo contains bar) { ..
真可惜。这被解析为(!foo).contains(bar)
. 不是我们想要的。
或者假设您需要另外添加一个新条件,并且您将其修改为:
if(foo contains bar && cond) { ..
另一个无赖。这被解析为foo.contains(bar.&&(cond))
. 又不是我们想要的。
当然,您可以在周围添加一堆括号,但与点符号相比,这将是丑陋且难以阅读/编辑的。
现在,我上面所说的所有内容也适用于符号方法名称。然而,符号方法在与点语法一起使用时看起来不自然,因此我更喜欢它们的中缀语法。
上述指南的一个例外:内部 DSL。它们通常精心制作,以免在以文档/示例中规定的方式(通常使用中缀表示法)编写时导致解析问题。
这是个人喜好的问题。您决定使用一种风格或另一种风格应该基于使您的代码最易读的因素。
但请注意,省略点和括号的能力仅限于某些句法结构,因此有时您只需要退回使用它们即可。
Scala 官方站点文档中有一个很好的样式指南,描述了正确使用中缀符号而不是点符号。
后缀符号:
names.toList
// is the same as
names toList // Unsafe, don't use!
Arity-1:
// right!
names foreach (n => println(n))
names mkString ","
optStr getOrElse "<empty>"
// wrong!
javaList add item
高阶函数:
// wrong!
names.map (_.toUpperCase).filter (_.length > 5)
// right!
names map (_.toUpperCase) filter (_.length > 5)
符号方法/运算符:
// right!
"daniel" + " " + "Spiewak"
// wrong!
"daniel"+" "+"spiewak"
我发现map
当我使用cats库创建笛卡尔坐标时,使用中缀表示法效果很好。例如:
(fetchIt(1) |@| fetchIt(2) |@| fetchIt(3)).map(MyCaseClass)
您可以像这样摆脱周围的括号:
fetchIt(1) |@| fetchIt(2) |@| fetchIf(3) map MyCaseClass
在我看来,第二个变体读起来更好。我想是口味问题。只是想增加我两美分的价值。
以上工作,因为|
在“|@|” 优先级高于m
“地图”。阅读 Scala 语言规范的这一部分以了解更多详细信息:
如果表达式中有多个中缀操作,则具有较高优先级的运算符比具有较低优先级的运算符绑定得更紧密。
http://scala-lang.org/files/archive/spec/2.12/06-expressions.html#infix-operations