fn调用在编译时没有执行

时间:2013-04-04 08:20:51

标签: clojure

我在一个ns中定义了以下内容 -

有一个服务原子,另一个要添加到该原子的函数 -

(ns ex.first)

(def services (atom []))

(defn add-service
  [fns]
  (swap! services conj fns))

在另一个ns的代码中,我这样做 -

(ns ex.second ..)

(add-service [fn1 fn2 fn3])

1)我假设当我运行编译代码的repl时,它应该将向量添加到原子中。但是当我评估@services时,它会返回[]

2)如果我在repl中评估(add-service [fn1 fn2 fn3]),则上述情况有效。

3)我也尝试过将add-service fn转换为宏。但是我发现@services仍然是空的。

如果有人能帮助解决这些问题,我们将不胜感激。

1)为什么在 -

时,add-service调用不会在代码编译时向atom添加向量
  • add-service被定义为fn
  • add-service被定义为macro

2)我如何使它工作:)

1 个答案:

答案 0 :(得分:4)

这取决于您是否在project.clj中将:aot设置为:all

如果:aot:all,则只要启动repl就会执行函数调用,否则您需要加载ex.second命名空间(例如:使用use )。加载将导致ns被编译,相应的类将被加载到jvm中,函数调用将被执行。

此外,函数调用不会在编译时发生,它发生在jvm加载编译的类(表示命名空间)时。

更新(根据评论):

如果你把它变成一个宏,那么你也需要考虑一下它。

如果aot设置为编译命名空间,则lein将创建一个jvm,在其中加载代码,调用clojure编译器,这将读取代码,执行宏并编译代码,此时这个jvm(这是用于编译你的代码)将有services原子填充的宏执行,但这个jvm只用于编译。然后lein将为run命令创建另一个jvm并在该jvm中加载已编译的类,但是这个jvm将不会填充services因为类没有任何填充它的代码。

如果未设置aot,那么宏将起作用,因为read,macroexpand,编译过程将在lein run jvm中发生,但仅在你加载ns时才会发生。

就“不加载ns”而言,您可以做的是将ex.second放在project.clj的:aot