我认为你正在学习 Scala 很棒。它背后有一个很棒的社区,非常活跃,我认为随着时间的推移,你会对你的决定越来越满意。
至少就目前而言,我认为您应该坚持使用“Scala 编程”,因为它写得非常好,并且是对这门语言的精彩介绍。然后,一个很好的地方是 Scala api 文档本身,因为许多类/方法都包含示例代码。此外,谷歌小组非常活跃(正如我所说,那里的人非常友好)。
请记住,您作为示例提供的代码不返回任何值,而只是产生副作用(在 Java 中,这将有一个void
返回值)。大多数 Scala API 都针对几乎没有返回值的副作用的函数(例如,您可能有日志记录的副作用,但惯用的 scala 代码将最大限度地减少方法和函数的副作用)。
在 Scala API 中,如果符合您的需要,有些方法将是首选样式。例如,在 Scheme 中你可能会做一个内部循环来迭代,在 Scala 中它可能看起来像这样:
val myScores = List(4, 8, 6, 1, 2, 4, 9, 8)
def max(ls: List[Int]): Int = {
def iter(acc: Int, rem: List[Int]): Int = {
if (rem.isEmpty) acc
else if (rem.head > acc) iter(rem.head, rem.tail)
else iter(acc, rem.tail)
}
iter(ls.head, ls)
}
但我不需要编写该函数,因为max
列表 API 中已经实现:
myScores.max
所以,如果你想做的事情已经被一个库实现了,你应该使用它。max()
是一个简单的例子,但在 Scala API 中可以找到更复杂的转换,并且scalaz
A for
-comprehension(您帖子的原始主题)是flatMap
、map
和. 的组合filter
。如果您正在做一些相当简单的事情,那么两个版本都将具有同样的可读性,但如果您正在做一长串flatMap
,map
和filter
串在一起以创建一个复杂的转换,那么for
-comprehension 将更具可读性。
编辑:
具体到您的问题,我认为for
-comprehension 版本更易于阅读:
val filterMapFlatmapVersion: List[String] =
fileNames.filter(_.endsWith("txt")).flatMap { file =>
io.Source.fromFile(file).getLines().toList.map(_.trim).filter(_ == pattern)
}
val forVersion: List[String] =
for {
fileName <- fileNames
if fileName.endsWith("txt")
line <- io.Source.fromFile(fileName).getLines()
if line.trim().matches(pattern)
} yield line.trim