scala中toString和mkString有什么区别?

时间:2012-03-17 04:29:51

标签: java string scala tostring

我有一个包含10行的文件 - 我想检索它,然后用换行符(“\ n”)分隔符拆分它们。

这就是我做的事情

val data = io.Source.fromFile("file.txt").toString;

但是当我尝试在换行符上拆分文件时,这会导致错误。

然后我尝试了

val data = io.Source.fromFile("file.txt").mkString;

它有效。

到底是什么?有人能告诉我这两种方法有什么区别吗?

4 个答案:

答案 0 :(得分:34)

让我们来看看这些类型,好吗?

scala> import scala.io._
import scala.io._

scala> val foo = Source.fromFile("foo.txt")
foo: scala.io.BufferedSource = non-empty iterator

scala> 

现在,您已将文件foo.txt读入的变量是迭代器。如果对其执行toString()调用,则不会返回文件的内容,而是返回您创建的迭代器的String表示形式。 OTOH,mkString()读取迭代器(即迭代它)并根据从中读取的值构造一个长String。

有关详细信息,请查看此控制台会话:

scala> foo.toString
res4: java.lang.String = non-empty iterator

scala> res4.foreach(print)
non-empty iterator
scala> foo.mkString
res6: String = 
"foo
bar
baz
quux
dooo
"

scala> 

答案 1 :(得分:24)

toString方法应该返回对象的字符串表示形式。它经常被覆盖以提供有意义的表示。 mkString方法是在集合上定义的,是一种将集合的元素与提供的字符串连接起来的方法。例如,尝试类似:

val a = List("a", "b", "c")
println(a.mkString(" : "))

你会得到“a:b:c”作为输出。 mkString方法通过使用您提供的字符串连接集合的元素,从集合中创建了一个字符串。在您发布的特定情况下,mkString调用将BufferedSource迭代器返回的元素与空字符串连接起来(这是因为您调用了没有参数的mkString)。这导致简单地将集合中的所有字符串(由BufferedSource迭代器产生)连接在一起。

另一方面,在这里调用toString并没有多大意义,因为你得到的(当你没有得到错误时)是BufferedSource迭代器的字符串表示形式;它只是告诉你迭代器是非空的。

答案 2 :(得分:2)

他们在不同的班级中有不同的方法。在这种情况下,mkString是特征GenTraversableOnce中的一种方法。 toString在Any上定义(并且经常被覆盖)。

最简单的方法(或至少我通常使用的方式)找出这个是使用http://www.scala-lang.org/api/current/index.html处的文档。从您的变量类型开始:

val data = io.Source.fromFile("file.txt")

的类型为

scala.io.BufferedSource

转到BufferedSource的文档,然后查找mkString。在mkString的文档中(点击左下方的向下箭头),您会看到它来自

Definition Classes TraversableOnce → GenTraversableOnce

用toString做同样的事情。

答案 3 :(得分:1)

我认为问题是要了解Source类正在做什么。从您的代码中可以看出,您希望Source.fromFile检索文件的内容,而它实际上是指向文件的开头。

这在使用I / O操作时很常见,您必须打开与资源的“连接”(在这种情况下是与文件系统的连接),多次读/写然后关闭该“连接”。在您的示例中,您打开了与文件的连接,并且必须每行读取文件的内容,直到结束。认为当你读到你正在内存中加载信息时,所以在大多数情况下(mkString将要做的)将整个文件加载到内存中并不是一个好主意。

另一方面,mkString用于迭代集合的所有元素,因此在这种情况下,读取文件并在内存中加载Array [String]。要小心,因为如果文件太大,您的代码将失败,通常在使用I / O时,您应该使用缓冲区来读取某些内容,然后处理/保存该内容,然后加载更多内容(在同一缓冲区中),避免出现问题有记忆。例如,阅读5行 - >解析 - >保存已解析的行 - >阅读接下来的5行 - >等

您还可以理解“toString”没有检索到任何内容......只是告诉您“您可以读取行,文件不为空”。