根据line-seq的ClojureDocs条目(http://clojuredocs.org/clojure_core/clojure.core/line-seq)和堆栈问题的接受答案(In Clojure 1.3, How to read and write a file),当传递java.io.BufferedReader时,line-seq应该返回一个惰性seq。
但是,当我在REPL中测试它时,类型被列为clojure.lang.Cons。请参见以下代码:
=> (ns stack-question
(:require [clojure.java.io :as io]))
nil
=> (type (line-seq (io/reader "test-file.txt")))
clojure.lang.Cons
=> (type (lazy-seq (line-seq (io/reader "test-file.txt"))))
clojure.lang.LazySeq将line-seq调用封装在lazy-seq调用中会得到一个lazy seq,但根据文档,这不应该是必需的: line-seq无论如何都应该返回一个lazy seq。
注意:在REPL (我正在使用nrepl)中,似乎完全实现了惰性seqs,所以我认为这可能只是REPL的一个怪癖;然而,当我用Speclj测试它时,同样的问题也存在。另外,我不认为实现一个懒惰的seq与正在发生的事情有什么关系。
编辑:所以我去检查了源代码后,mobyte的答案说,有一个懒惰的seq在尾部的cons…
1 (defn line-seq
2 "Returns the lines of text from rdr as a lazy sequence of strings.
3 rdr must implement java.io.BufferedReader."
4 {:added "1.0"}
5 [^java.io.BufferedReader rdr]
6 (when-let [line (.readLine rdr)]
7 (cons line (lazy-seq (line-seq rdr)))))对cons的调用可以解释为什么line-seq的返回值类型是clojure.lang.Cons。
发布于 2013-03-03 13:36:45
你不需要“包装”输出尾巴,因为它已经有了“Cons”作为“尾巴”:
(type (line-seq (io/reader "test-file.txt")))
=> clojure.lang.Cons
(type (rest (line-seq (io/reader "test-file.txt"))))
=> clojure.lang.LazySeq
(type (cons 'a (rest (line-seq (io/reader "test-file.txt")))))
=> clojure.lang.Cons编辑。
注意:在REPL (我用的是nrepl)中,似乎完全实现了懒惰的seqs
不正确。您可以对其进行测试:
(with-open [r (io/reader "test-file.txt")] (line-seq r))
=> IOException Stream closed java.io.BufferedReader.ensureOpen (BufferedReader.java:97)这是因为line-seq返回未完全实现的lazy-seq,并且当reader稍后尝试实现结果以打印它时,repl已经关闭。但如果你明确地意识到这一点,它会给出正常的结果,没有任何异常:
(with-open [r (io/reader "/home/mobyte/2")] (doall (line-seq r)))
=> ... output ...https://stackoverflow.com/questions/15182702
复制相似问题