这是预期的行为,还是我的Clojure安装问题(我在Windows和Linux上检查它)?
我有一个简单的项目,用lein new app testfor.这是代码src/testfor/core.clj:
(ns testfor.core
(:gen-class))
(defn -main [& args]
(println "hello")
(for [x [1 2 3]]
(println x)))
Run Code Online (Sandbox Code Playgroud)
当我从REPL 运行lein repl并调用时(-main),输出是这样的:
testfor.core=> (-main)
hello
1
2
3
Run Code Online (Sandbox Code Playgroud)
但后来我运行应用程序lein run,或者lein uberjar运行生成的JAR文件,输出是这样的:
$ lein run
hello
Run Code Online (Sandbox Code Playgroud)
所以,它以某种方式不运行for循环.
我在这里做错了吗?
我相信这是因为for返回一个懒惰的元素序列 - https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/for
在-main从repl 调用函数的示例中,在这种情况下,函数中的最后一个表达式从函数调用返回(就像任何其他函数调用一样).REPL看到lazy-seq并尝试打印它,这需要实现seq,它将评估println语句.
在Leiningen调用main方法的示例中,它就像在具有void返回类型的Java类上调用main方法public static void main.Clojure会把它视为懒惰,没有任何东西试图实现seq,因此println表达式永远不会被评估.
for不是像 Java 中的 for 循环。它创建一个惰性序列,该序列取决于您指定的不同选项。请参阅参考资料文档。
在你的案例中,重要的一点是懒惰这个词。repl 实际上会强制实现惰性序列,但是当使用 运行时lein,情况并非如此。为了做你想做的事,你需要强制使用dorunor doall:
(defn -main [& args]
(println "hello")
(dorun (for [x [1 2 3]]
(println x))))
cuvier:tgo$ lein run
hello
1
2
3
Run Code Online (Sandbox Code Playgroud)