3

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

这一次,所有的输出都到标准输出,文件是空的。这里发生了什么?

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

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

1 回答 1

5

你被懒虫咬了。

在 for 和绑定内放置一个doalldorun

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

在您的示例中,打印正在发生,然后从绑定返回结果由 repl 打印。所以在印刷时装订不再到位。

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

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绑定中返回的惰性序列,则不会将任何内容打印到 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) 

相反,输出最终出现在文件中:

arthur@a:~/hello$ cat test.txt 
Hi 1
Hi 2
于 2013-02-15T21:03:16.083 回答