假设我有一个大文本文件,其格式如下:
部分开始 ... ... ... 部分结束 部分开始 ... ... ... 部分结束 ....
我想解析文件并逐段使用它,但是我不想将整个内容保存在内存中,我想读取一个部分并对该部分进行一些操作,例如将其插入数据库,然后丢弃它并继续阅读下一节,我应该如何以一种功能性的方式做到这一点?我只能通过操纵可变变量来提出一些实现。
假设我有一个大文本文件,其格式如下:
部分开始 ... ... ... 部分结束 部分开始 ... ... ... 部分结束 ....
我想解析文件并逐段使用它,但是我不想将整个内容保存在内存中,我想读取一个部分并对该部分进行一些操作,例如将其插入数据库,然后丢弃它并继续阅读下一节,我应该如何以一种功能性的方式做到这一点?我只能通过操纵可变变量来提出一些实现。
您总是可以通过编写(尾)递归函数来解决这些问题*
def parseLines(
in: Iterator[String],
thisSection: List[String] = Nil,
results: List[Foo] = Nil
): List[Foo] = {
if (!in.hasNext) results.reverse
else in.next match {
case "SECTION END" =>
val section = thisSection.reverse.drop(1)
// Do something with data
val foo = // whatever you need to store from this section
parseLines(in, Nil, foo :: results)
case s =>
parseLines(in, s :: thisSection, results)
}
}
但这样做并不总是比使用可变变量更好。关键是保持你的可变性得到很好的保护,这样变化的状态就不会泄露出来并使程序其余部分的逻辑复杂化。在这样的方法中添加累加器变量而不是使其递归也是完全可以的;选择使逻辑更清晰的那个。
*最好是尾递归,否则堆栈会溢出。使用@tailrec
注释来确定。