2017-10-18 6 views
1

をブロックし、最終的にそれを閉じようとすると、正常に動作します:問題のコードスニペット後

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) 
    ... 

また、タイプをに変更すると次の例外がスローされます。それは再び動作します。

toSeqは実際には完全に消費されずにいくらか遅れている部分的にレイジーなストリームを生成するように感じます。

フードの中で何が起こるか説明できますか?

答えて

1

本当にあなたは正しいです。さんはSource.fromURLから始まるそれを追跡してみましょう:toStreamdef toSeq: Seq[A] = toStream

  • 実装は次のとおりです。

    1. Source.fromURL =>scala.io.BufferedSource
    2. BufferedSource.getLines =>BufferedLineIterator
    3. BufferedLineIterator.toSeqscala.collection.TraversableOnce
    4. TraversableOnceの方法toSeqを実装してから呼び出されますクラスIteratorから取られました。

      def toStream: Stream[A] = 
          if (self.hasNext) Stream.cons(self.next(), self.toStream) 
          else Stream.empty[A] 
      

      ふう、かなりの旅:

    実装は次のようです。はい、あなたは怠け者であるストリームを構築することになります。したがって、あなたはその質問で言及した例外を取得します。

  • +0

    ありがとうございました。この場合、 'TraversableOnce'が' Stream'を使う理由は?私は最初に、おそらくそれが原則的に怠け者の一部であるBufferedSourceを扱うという事実と関係があると考えました。しかし、確かに言うことはできません。 –

    関連する問題