我认为你学习 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
-理解(你帖子的原始主题)是以下内容的组合flatMap
, map
, and filter
。如果您正在做一些相当简单的事情,那么两个版本都将具有相同的可读性,但如果您正在做一长串flatMap
, map
, and filter
串在一起创建一个复杂的转换,然后for
- 理解将更具可读性。
EDIT:
具体到你的问题,我认为for
-理解版本更容易阅读:
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