我是Clojure的新手,我试图通过重新绑定将输出重定向到文件*out*
.在一个简单的例子中,它很好地工作:
(binding [*out* (new java.io.FileWriter "test.txt")]
(println "Hi"))
Run Code Online (Sandbox Code Playgroud)
这符合我的预期,将"Hi"打印到文件test.txt.但是,如果我引入一个for
循环,事情就会出错:
(binding [*out* (new java.io.FileWriter "test.txt")]
(for [x [1 2]]
(println "Hi" x)))
Run Code Online (Sandbox Code Playgroud)
这次,所有输出都转到stdout,文件为空.这里发生了什么?
我正在使用Leiningen,如果这有任何区别:
Leiningen 2.0.0 on Java 1.7.0_13 Java HotSpot(TM) 64-Bit Server VM
Run Code Online (Sandbox Code Playgroud)
你被这个懒惰的小虫咬了.
放置一个doall
或dorun
围绕for和绑定
(binding [*out* (new java.io.FileWriter "test.txt")]
(doall (for [x [1 2]]
(println "Hi" x))))
Run Code Online (Sandbox Code Playgroud)
在您的示例中,正在进行打印,然后在从绑定返回后由repl打印结果.因此,在打印时,绑定不再存在.
没有打印任何内容,因为结果是一个惰性序列,稍后将在使用时进行评估
user> (def result (binding [*out* (new java.io.FileWriter "test.txt")]
(for [x [1 2]]
(println "Hi" x))))
#'user/result
Run Code Online (Sandbox Code Playgroud)
当repl打印结果时,将评估printlns:
user> result
(Hi 1
Hi 2
nil nil)
Run Code Online (Sandbox Code Playgroud)
如果我们强制评估for
绑定中返回的延迟序列,则不会将任何内容打印到repl,
user> (def result (binding [*out* (new java.io.FileWriter "test.txt")]
(doall (for [x [1 2]]
(println "Hi" x)))))
#'user/result
user> result
(nil nil)
Run Code Online (Sandbox Code Playgroud)
而输出最终在文件中:
arthur@a:~/hello$ cat test.txt
Hi 1
Hi 2
Run Code Online (Sandbox Code Playgroud)