File io 为什么seq行返回clojure.lang.Cons而不是clojure.lang.LazySeq?

File io 为什么seq行返回clojure.lang.Cons而不是clojure.lang.LazySeq?,file-io,clojure,lazy-sequences,cons,File Io,Clojure,Lazy Sequences,Cons,根据line seq()的ClojureDocs条目和Stack question()的可接受答案,line seq在传递java.io.BufferedReader时应返回惰性seq 但是,当我在REPL中测试时,该类型被列为clojure.lang.Cons。请参阅下面的代码: => (ns stack-question (:require [clojure.java.io :as io])) nil => (type (line-seq (io/reader "tes

根据line seq()的ClojureDocs条目和Stack question()的可接受答案,line seq在传递java.io.BufferedReader时应返回惰性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),似乎懒惰的seq得到了充分的实现,所以我认为这可能只是REPL的一个怪癖;然而,当我用Speclj测试它时,同样的问题也存在。另外,我不认为实现一个懒惰的seq与正在发生的事情有任何关系

编辑: 所以在mobyte的回答说在cons的尾部有一个懒惰的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的调用可以解释为什么seq行的返回值类型是clojure.lang.cons。

您不需要“wrap”输出
cons
,因为它已经将惰性seq作为“tail”:

编辑。

注意:在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
未完全实现,并且当repl稍后尝试实现结果并打印时,
reader
已经关闭。但如果您明确意识到这一点,它将给出正常的结果,没有任何例外:

(with-open [r (io/reader "/home/mobyte/2")] (doall (line-seq r)))
=> ...  output ...
所以我假设在REPL中键入(line seq my buffered reader)并将其完全打印出来意味着仅在打印步骤中对惰性seq进行评估,但实际上直到那时才进行评估?
(with-open [r (io/reader "/home/mobyte/2")] (doall (line-seq r)))
=> ...  output ...