我是Clojure的新手,正在尝试通过重新绑定*out*将输出重定向到文件。在一个简单的情况下,它可以很好地工作:

(binding [*out* (new java.io.FileWriter "test.txt")]
  (println "Hi"))


这符合我的预期,将“ Hi”打印到文件test.txt。但是,如果引入一个for循环,事情就会出错:

(binding [*out* (new java.io.FileWriter "test.txt")]
  (for [x [1 2]]
    (println "Hi" x)))


这次,所有输出都转到stdout,文件为空。这里发生了什么?

我正在使用Leiningen,如果有什么不同:

Leiningen 2.0.0 on Java 1.7.0_13 Java HotSpot(TM) 64-Bit Server VM

最佳答案

您已经被这个懒虫咬了。

在for和绑定内放置doalldorun

(binding [*out* (new java.io.FileWriter "test.txt")]
  (doall (for [x [1 2]]
           (println "Hi" x))))


在您的示例中,正在进行打印,然后从装订返回结果后,结果将由repl打印。因此,在打印时,装订不再有效。

没有打印任何内容,因为结果是一个惰性序列,稍后将在使用时对其进行评估

user> (def result (binding [*out* (new java.io.FileWriter "test.txt")]
        (for [x [1 2]]
          (println "Hi" x))))
#'user/result


当repl打印结果时,将对printlns进行评估:

user> result
(Hi 1
Hi 2
nil nil)


如果我们强制评估绑定中for返回的惰性序列
什么都没有印到副本,

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)


而是输出最终出现在文件中:

arthur@a:~/hello$ cat test.txt
Hi 1
Hi 2

关于clojure - Clojure输出绑定(bind)在for循环中重置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14902718/

10-10 01:03
查看更多