Clojure输出绑定在for循环中重置

sha*_*naw 3 clojure leiningen

我是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)

Art*_*ldt 5

你被这个懒惰的小虫咬了.

放置一个doalldorun围绕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)