gpt4 book ai didi

clojure - 为什么 `lein uberjar` 评估用 `def` 定义的变量?

转载 作者:行者123 更新时间:2023-12-04 10:36:30 24 4
gpt4 key购买 nike

我试图在创建 uberjar 时理解“Lieningen”行为.以下是重现行为的最小示例:

(ns my-stuff.core
(:gen-class))

(def some-var (throw (Exception. "boom!")))

(defn -main [& args]
(println some-var))

当使用 lein run 执行时它显然因异常而失败。但是,我不明白为什么要执行 lein uberjar也因变量定义中的异常而失败?为什么要执行 lein uberjar尝试评估变量值?这是特定于 uberjar 的吗?任务还是我错过了有关 Clojure 或 Leiningen 的更重要的内容?

最佳答案

为了为 uberjar 编译你的命名空间(如果你打开了 AOT),clojure 编译器必须加载你的命名空间。这将始终调用所有顶级副作用。

处理这个问题的最好方法是不要在顶级代码中产生副作用(无论是在 def 表单内部还是外部),并具有初始化函数来实现所需的任何启动副作用。

一种解决方法是创建一个小的命名空间,它使用自省(introspection)在运行时加载其余代码,而不是在编译时加载 - 使用如下函数:

(defn -main
[]
(require 'my.primary.ns)
((resolve 'my.primary.ns/start)))

如果该命名空间已编译,则 jvm 可以找到 -main 并运行它,尽管没有编译您的其他代码。运行时 require将导致 Clojure 编译器仅在运行时加载其余代码,并且 resolve需要 -main将编译干净 - 它返回引用的 var,然后在调用时调用您的函数。

关于clojure - 为什么 `lein uberjar` 评估用 `def` 定义的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32288195/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com