Clojure的-main函数没有完全执行

ant*_*one 1 clojure

这是预期的行为,还是我的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循环.

我在这里做错了吗?

Hug*_*ugo 5

我相信这是因为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表达式永远不会被评估.


T.G*_*lle 5

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)