Clojure 什么';这个函数的返回值是多少?
我写了这个函数,但是它的返回值是多少Clojure 什么';这个函数的返回值是多少?,clojure,Clojure,我写了这个函数,但是它的返回值是多少 (defn read-data [file] (let [code (subs (.getName file) 0 3)] (with-open [rdr (clojure.java.io/reader file)] (drop 1 (line-seq rdr))))) (def d (read-data "data.db")) 直到现在还可以。但当我想打印出来的时候 (clojure.pprint/pprint d) 我有一个
(defn read-data [file]
(let [code (subs (.getName file) 0 3)]
(with-open [rdr (clojure.java.io/reader file)]
(drop 1 (line-seq rdr)))))
(def d (read-data "data.db"))
直到现在还可以。但当我想打印出来的时候
(clojure.pprint/pprint d)
我有一个例外:
Exception in thread "main" java.lang.RuntimeException: java.io.IOException: Stream closed
所以我很困惑,怎么了?返回值不是一个列表?作为新手,在这种情况下如何调试
谢谢
(drop 1 (line-seq rdr))
此行返回一个序列,即惰性或流。因此,当执行这一行时,文件读取器rdr基本上不会被实际读取,但当您尝试在打印方法中访问此序列时,rdr会被行序列
函数读取,但当您使用with open
时,当执行从with open
流出时,rdr已经关闭
请参阅
doall
,以便在创建惰性序列时对其进行求值。我建议您阅读FP中的惰性,尤其是序列,以便Clojure更好地理解惰性评估。问题在于行序列
是惰性的,并且在评估时阅读器已关闭
这意味着所有行都需要在使用open的范围内读取。一个选项是使用doall
强制对line seq
进行完整评估,如下所示
(drop 1 (doall (line-seq rdr)))
这种方法的一个潜在问题是,如果文件大于可用内存,则会出现OutOfMemoryError。因此,根据您试图实现的目标,可能还有其他内存占用较少的解决方案。例如,您可以使用close和修改后的“line seq”来自动关闭读卡器:
(defn line-seq2 [^java.io.BufferedReader rdr]
(if-let [line (.readLine rdr)]
(cons line (lazy-seq (line-seq2 rdr)))
(.close rdr)))
(defn my-reader [file]
(let [lines (line-seq (clojure.java.io/reader file))]
(fn [] lines)))
(def d (my-reader "data.db"))
现在变量“d”是一个函数:
user> (drop 1 (d))
=> ... file body except first line ...