Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 将文件行的延迟序列传递给函数_Clojure - Fatal编程技术网

Clojure 将文件行的延迟序列传递给函数

Clojure 将文件行的延迟序列传递给函数,clojure,Clojure,为什么这段代码不起作用 (defn with-file [fname fn] (with-open [r (reader fname)] (fn (line-seq r)))) (with-file "data/input_d2" (fn [x] (map count x))) 我正在打开一个文件,当它打开时,我正在向提供的函数传递一个延迟的行序列 (defn with-file [fname fn] (with-open [r (reader fname

为什么这段代码不起作用

(defn with-file [fname fn]
  (with-open [r (reader fname)]
    (fn (line-seq r))))

(with-file "data/input_d2" (fn [x] (map count x)))
我正在打开一个文件,当它打开时,我正在向提供的函数传递一个延迟的行序列

(defn with-file [fname fn]
  (with-open [r (reader fname)]
    (doall (fn (line-seq r)))))

(with-file "data/input_d2" (fn [x] (map count x)))
我得到的错误是:

Error printing return value (IOException) at java.io.BufferedReader/ensureOpen (BufferedReader.java:122).
Stream closed
我刚想出来。 因为行seq是惰性的,所以它上的所有操作都返回惰性seq。 因此,调用with file函数会返回一个lazy seq,REPL稍后会尝试对其求值,但此时文件已经关闭

因此,我们需要强制计算从传递的函数返回的内容

(defn with-file [fname fn]
  (with-open [r (reader fname)]
    (doall (fn (line-seq r)))))

(with-file "data/input_d2" (fn [x] (map count x)))
我刚想出来。 因为行seq是惰性的,所以它上的所有操作都返回惰性seq。 因此,调用with file函数会返回一个lazy seq,REPL稍后会尝试对其求值,但此时文件已经关闭

因此,我们需要强制计算从传递的函数返回的内容

(defn with-file [fname fn]
  (with-open [r (reader fname)]
    (doall (fn (line-seq r)))))

(with-file "data/input_d2" (fn [x] (map count x)))

另外,请澄清参数名称,如
fn
=>
f
fn
。另外,我会直接用
doall
vec
来包装
行序列
,比如:
(f(vec(lineseq r)))
。直接用doal来包装行序列不会破坏使用惰性序列的整个目的吗?它将全部加载到内存中,但对于大多数目的来说,这并没有什么区别。除非确实需要延迟处理管道,否则我喜欢将
doall
vec
放在需要的地方。如果你把它放在一个长的处理链的末端,它为什么会在那里并不明显,当有人改变或删除一个“不需要的”步骤时,它可能会导致错误。特别是如果最后一步像将
mapv
更改为
map
这样微妙,我不同意艾伦的观点。我会坚持使用
doall
在您拥有它的地方:使用open围绕
内部的代码体。直接将
doall
包装在
行seq
代码周围将强制将其全部读取到内存中,如果传入的
fn
减少了数据大小——就像这个
(map count x)
所做的那样——您将希望在非常大的文件上使用
行seq
的惰性,使用文件
内部执行doall还有另一个风险-它期望
fn
返回一个序列。例如,如果在
上爆炸(使用文件…计数)
。我希望
fn
不要偷懒。另外,请澄清参数名称,如
fn
=>
f
fn
。另外,我会直接用
doall
vec
来包装
行序列
,比如:
(f(vec(lineseq r)))
。直接用doal来包装行序列不会破坏使用惰性序列的整个目的吗?它将全部加载到内存中,但对于大多数目的来说,这并没有什么区别。除非确实需要延迟处理管道,否则我喜欢将
doall
vec
放在需要的地方。如果你把它放在一个长的处理链的末端,它为什么会在那里并不明显,当有人改变或删除一个“不需要的”步骤时,它可能会导致错误。特别是如果最后一步像将
mapv
更改为
map
这样微妙,我不同意艾伦的观点。我会坚持使用
doall
在您拥有它的地方:使用open
围绕
内部的代码体。直接将
doall
包装在
行seq
代码周围将强制将其全部读取到内存中,如果传入的
fn
减少了数据大小——就像这个
(map count x)
所做的那样——您将希望在非常大的文件上使用
行seq
的惰性,使用文件
内部执行doall还有另一个风险-它期望
fn
返回一个序列。例如,如果在
上爆炸(使用文件…计数)
。我宁愿希望
fn
不要懒惰。