根据 ClojureDocs 中 line-seq 的条目(http://clojuredocs.org/clojure_core/clojure.core/line-seq http://clojuredocs.org/clojure_core/clojure.core/line-seq)以及堆栈问题的公认答案(在 Clojure 1.3 中,如何读写文件 https://stackoverflow.com/questions/7756909/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
在lazy-seq调用中包装line-seq调用会给出一个lazy seq,但根据文档,这应该不是必需的:line-seq无论如何都应该返回一个lazy seq。
笔记:
在 REPL 内部(我正在使用 nrepl),似乎惰性 seq 得到了完全实现,所以我认为这可能只是 REPL 的一个怪癖;然而,当我用 Speclj 测试它时,也存在同样的问题。另外,我认为实现惰性序列与正在发生的事情无关。
编辑:
所以我在mobyte的回答说cons尾部有一个lazy seq后去检查源代码......
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。
您不需要“换行”输出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
Edit.
注意:在 REPL 内部(我正在使用 nrepl),惰性 seq 似乎得到了
完全实现
不正确。你可以测试一下:
(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 ...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)