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 run
或 lein 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
的时候就不是这样了。为了做你想做的事,你需要强制使用 dorun
或 doall
:
(defn -main [& args]
(println "hello")
(dorun (for [x [1 2 3]]
(println x))))
cuvier:tgo$ lein run
hello
1
2
3
这是预期的行为,还是我的 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 run
或 lein 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
的时候就不是这样了。为了做你想做的事,你需要强制使用 dorun
或 doall
:
(defn -main [& args]
(println "hello")
(dorun (for [x [1 2 3]]
(println x))))
cuvier:tgo$ lein run
hello
1
2
3