这是预期的行为,还是我的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)))
当我从REPL运行lein repl
并调用(-main)
时,输出为:
testfor.core=> (-main)
hello
1
2
3
然后我用lein run
或lein uberjar
运行应用程序并运行生成的JAR文件,输出为:
$ lein run
hello
因此,它以某种方式不运行for
循环。
我在这里做错了吗?
答案 0 :(得分:5)
我相信这是因为for
会返回一个懒惰的元素序列 - https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/for
在从repl调用-main
函数的示例中,在这种情况下,函数中的最后一个表达式从函数调用返回(就像任何其他函数调用一样)。 REPL看到lazy-seq并尝试打印它,这需要实现seq,它将评估println
语句。
在Leiningen调用main方法的示例中,它类似于在具有void返回类型public static void main
的Java类上调用main方法。 Clojure会将其视为懒惰,并且没有尝试实现seq,因此永远不会评估println
表达式。
答案 1 :(得分:3)
for
不像Java那样是for循环。它会创建一个延迟序列,该序列取决于您指定的不同选项。请参阅for文档。
您的案例中的重点是 lazy 字。
repl实际上会强制实现延迟序列,但是当使用lein
运行时,情况并非如此。为了做你想做的事,你需要强制使用dorun
或doall
:
(defn -main [& args]
(println "hello")
(dorun (for [x [1 2 3]]
(println x))))
cuvier:tgo$ lein run
hello
1
2
3