带有大量方法链接的Scala代码的接受/推荐语法是什么? [英] What is the accepted/recommended syntax for Scala code with lots of method-chaining?
问题描述
在Scala中,相对于许多带有 val
赋值的较小表达式,我倾向于写大型链表达式。在我公司,我们已经为这种类型的代码开发了一种样式。这是一个完全人为的示例(想法是显示带有许多链接调用的表达式):
In Scala I tend to favour writing large chained expressions over many smaller expressions with val
assignments. At my company we've sort of evolved a style for this type of code. Here's a totally contrived example (idea is to show an expression with lots of chained calls):
import scala.util.Random
val table = (1 to 10) map { (Random.nextInt(100), _) } toMap
def foo: List[Int] =
(1 to 100)
.view
.map { _ + 3 }
.filter { _ > 10 }
.flatMap { table.get }
.take(3)
.toList
我普遍喜欢的
Daniel Spiewak的 Scala样式指南(pdf)建议链式方法调用中的前导点符号可能很糟糕(请参阅doc:方法调用/高阶函数),尽管它不能直接覆盖这样的多行表达式。
Daniel Spiewak's Scala Style Guide (pdf), which I generally like, suggests the leading dot notation in the chained method calls may be bad (see doc: Method Invocation / Higher-Order Functions), though it doesn't cover multi-line expressions like this directly.
是否存在另一种更通用的惯用方法来编写上面的函数 foo
?
Is there another, more accepted/idiomatic way to write the function foo
above?
更新:2011年6月28日
以下提供了很多很好的答案和讨论。似乎没有100%的您必须这样做的答案,因此,我将以投票方式接受最受欢迎的答案,这是目前用于理解的方法。就个人而言,我认为我现在将继续使用前导点表示法并接受其带来的风险。
Lots of great answers and discussion below. There doesn't appear to be a 100% "you must do it this way" answer, so I'm going to accept the most popular answer by votes, which is currently the for comprehension approach. Personally, I think I'm going to stick with the leading-dot notation for now and accept the risks that come with it.
推荐答案
该示例有点不现实,但是对于复杂的表达式,使用理解通常会更干净:
The example is slightly unrealistic, but for complex expressions, it's often far cleaner to use a comprehension:
def foo = {
val results = for {
x <- (1 to 100).view
y = x + 3 if y > 10
z <- table get y
} yield z
(results take 3).toList
}
这里的另一个优点是,您可以命名计算的中间阶段,并使它更具自记录性。
The other advantage here is that you can name intermediate stages of the computation, and make it more self-documenting.
但是如果您的目标是简洁,则可以轻松地将其变成单线(无点样式在这里有帮助):
If brevity is your goal though, this can easily be made into a one-liner (the point-free style helps here):
def foo = (1 to 100).view.map{3+}.filter{10<}.flatMap{table.get}.take(3).toList
//or
def foo = ((1 to 100).view map {3+} filter {10<} flatMap {table.get} take 3).toList
,并一如既往地优化算法:
and, as always, optimise your algorithm where possible:
def foo = ((1 to 100).view map {3+} filter {10<} flatMap {table.get} take 3).toList
def foo = ((4 to 103).view filter {10<} flatMap {table.get} take 3).toList
def foo = ((11 to 103).view flatMap {table.get} take 3).toList
这篇关于带有大量方法链接的Scala代码的接受/推荐语法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!