对于这两者,是否有最佳实践?我一直在阅读 Odersky 等人的 Scala 书籍,看起来中缀符号用于许多集合 API 函数,而点号则保留给程序员定义的函数。
对于这两者,是否有最佳实践?我一直在阅读 Odersky 等人的 Scala 书籍,看起来中缀符号用于许多集合 API 函数,而点号则保留给程序员定义的函数。
我个人没有任何硬性规定,但我倾向于仅在符号方法名称中使用中缀表示法,并在字母数字方法名称中使用点表示法。
中缀表示法使修改代码变得繁琐。以下是一些例子。
想象你有这行代码:
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。它们通常经过精心设计,以便在按照其文档/示例中所规定的方式(通常使用中缀符号)编写时不会引起解析问题。
这是个人喜好问题。你使用其中一种风格的决定应该基于哪种风格可以使你的代码最容易阅读。
但请注意,省略点和括号的能力仅限于某些句法结构,因此有时你只能使用它们。
a.op(b)
比a op b
长但比(a op b)
短。这是一个细微的差别,但它可以成为“最易读”的考虑因素之一。 - Rex Kerrnames.toList
// is the same as
names toList // Unsafe, don't use!
参数个数为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"
我发现在使用cats库创建笛卡尔积时,使用中缀符号表示map
非常方便。例如:
(fetchIt(1) |@| fetchIt(2) |@| fetchIt(3)).map(MyCaseClass)
你可以这样去掉周围的括号:
fetchIt(1) |@| fetchIt(2) |@| fetchIf(3) map MyCaseClass
在我看来,第二种变体读起来更好。我想这只是个人口味问题。只是想添砖加瓦。
上述代码之所以有效,是因为"|@|"中的|
比"map"中的m
具有更高的优先级。请阅读Scala语言规范的这一部分以了解更多细节:
如果表达式中有几个中缀操作符,则具有较高优先级的运算符比具有较低优先级的运算符更紧密地绑定。
http://scala-lang.org/files/archive/spec/2.12/06-expressions.html#infix-operations
(xs filter f map g).toList
仍然比xs.filter(f).map(g).toList
更清晰、更明显。 - Kevin WrightsomeExpression
=>someExpression.newPart
与(someExpression).newPart
之间的区别不显著。在两种情况下,都必须添加.newPart
。诚然,在第二种情况下需要添加括号,但你很可能一开始在第一种情况下就用了更少的括号。将“这可能会导致分号推断问题”的解释用作支持前一种方法的草人论法是错误的——这是添加后缀调用的一个症状,而不是原始表达式的问题。 - Kevin Wright