以下代码段工作正常:
def using[A, B <: {def close(): Unit}] (closeable: B) (f: B => A): A =
try { f(closeable) } finally { closeable.close() }
def loadDictionaryFromNet():List[String] =
using(Source.fromURL("http://www.mieliestronk.com/corncob_caps.txt", "UTF-8"))(_.getLines().toList)
val dictionary = loadDictionaryFromNet() filter(_.forall(_.isLetter))
但是当我尝试将类型更改为Seq[String]
时,如下所示:
def using[A, B <: {def close(): Unit}] (closeable: B) (f: B => A): A =
try { f(closeable) } finally { closeable.close() }
def loadDictionaryFromNet():Seq[String] =
using(Source.fromURL("http://www.mieliestronk.com/corncob_caps.txt", "UTF-8"))(_.getLines().toSeq)
val dictionary = loadDictionaryFromNet() filter(_.forall(_.isLetter))
然后抛出以下异常:
Exception in thread "main" java.io.IOException: stream is closed
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.ensureOpen(HttpURLConnection.java:3348)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3373)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
...
此外,当我将类型更改为IndexedSeq
时,它再次有效。
它“感觉”像toSeq
实际上会产生一些部分懒惰的流,它不能立即完全消耗,但有一些延迟。
你能解释一下发生了什么吗?
答案 0 :(得分:1)
确实你是对的。让我们从Source.fromURL
开始追踪它:
Source.fromURL
=&gt; scala.io.BufferedSource
BufferedSource.getLines
=&gt; BufferedLineIterator
BufferedLineIterator.toSeq
调用scala.collection.TraversableOnce
TraversableOnce
将方法toSeq
实现为:def toSeq: Seq[A] = toStream
toStream
的实施取自课程Iterator
。实施如下:
def toStream: Stream[A] =
if (self.hasNext) Stream.cons(self.next(), self.toStream)
else Stream.empty[A]
P P,相当一段旅程。是的,你最终构建了一个懒惰的流,因此你得到了你在问题中提到的异常。