Clojure 的 -main 函数未完全执行

Clojure's -main function not fully executed

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

当我 运行 lein repl 并从 REPL 调用 (-main) 时,输出是这样的:

testfor.core=> (-main)
hello
1
2
3

但是我 运行 应用程序 lein runlein uberjar 和 运行 生成的 JAR 文件,输出是这样的:

$ lein run
hello

所以,它不会 运行 for 循环。

我是不是做错了什么?

我相信这是因为 for return 是一个惰性元素序列 - https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/for

在您从 repl 调用 -main 函数的示例中,在这种情况下,函数中的最后一个表达式是 return 从函数调用中编辑的(就像任何其他函数调用一样) . REPL 看到 lazy-seq 并尝试打印它,这需要实现 seq,它将评估 println 语句。

在您 Leiningen 调用 main 方法的示例中,这就像在具有 void return 类型 public static void main 的 Java class 上调用 main 方法. Clojure 会将其视为惰性的,没有任何尝试实现 seq,因此永远不会评估 println 表达式。

for 不是像 Java 中那样的 for 循环。它会创建一个惰性序列,该序列取决于您指定的不同选项。请参阅 for 文档。

你的情况的重点是 lazy 这个词。 repl其实会强制实现lazy sequence,但是当运行lein的时候就不是这样了。为了做你想做的事,你需要强制使用 dorundoall :

(defn -main [& args]
  (println "hello")
  (dorun (for [x [1 2 3]]
           (println x))))


cuvier:tgo$ lein run
hello
1
2
3