如何在 clojure 中使用前向声明和跨命名空间的未绑定变量
How use Forward declaration in clojure and unbound variables across namespace
我在名为 "helpers"
的命名空间中声明了这个宏
(defmacro reply [name-key & arguments] ;;macro use BUS, it needs to be declared in this namespace
~(<! (reply* (~name-key BUS) arguments)))
我需要在其他命名空间 "core" 中使用它 使用映射
在这个命名空间中初始化 BUS 之后
(def BUS {:something "a"})
(reply ...)
仅当 BUS 在此命名空间中声明时,命名空间助手才会编译...我可以声明它,然后在我的特定命名空间中对其进行初始化
***helpers
(def BUS)
(declare BUS) ;;alternative
(defmacro reply... ) ;;using BUS in its body!
***other namespace
(def BUS {:a "b"})
(reply ...) ;; this macro use BUS
但这失败了
BUS already refers to: #'yourvertxproject.helper-fun/BUS in namespace: test1.core, compiling:(test1/core.clj:13:1)
这样做的正确方法是什么?...
注意:我注意到一些库实现了这一点,例如在 korma db 中,您使用数据库路径和配置初始化变量,然后您可以使用依赖于该变量的不同函数....
谢谢!...
我相信你正在寻找动态变量。
在您的 "helpers" 命名空间中,使用
声明 *bus*
(不是 "BUS")
(def ^:dynamic *bus*)
在创建宏之前。
然后,在您使用它的命名空间中,执行
(binding [*bus* {:a "b"}]
...)
(注意 binding
是线程本地的。)
在这种情况下,我还会使用带有限定命名空间的 :as
快捷方式来引用 "helpers",以便更容易看到 *bus*
是在别处定义的。
我在名为 "helpers"
的命名空间中声明了这个宏(defmacro reply [name-key & arguments] ;;macro use BUS, it needs to be declared in this namespace
~(<! (reply* (~name-key BUS) arguments)))
我需要在其他命名空间 "core" 中使用它 使用映射
在这个命名空间中初始化 BUS 之后(def BUS {:something "a"})
(reply ...)
仅当 BUS 在此命名空间中声明时,命名空间助手才会编译...我可以声明它,然后在我的特定命名空间中对其进行初始化
***helpers
(def BUS)
(declare BUS) ;;alternative
(defmacro reply... ) ;;using BUS in its body!
***other namespace
(def BUS {:a "b"})
(reply ...) ;; this macro use BUS
但这失败了
BUS already refers to: #'yourvertxproject.helper-fun/BUS in namespace: test1.core, compiling:(test1/core.clj:13:1)
这样做的正确方法是什么?...
注意:我注意到一些库实现了这一点,例如在 korma db 中,您使用数据库路径和配置初始化变量,然后您可以使用依赖于该变量的不同函数....
谢谢!...
我相信你正在寻找动态变量。
在您的 "helpers" 命名空间中,使用
声明*bus*
(不是 "BUS")
(def ^:dynamic *bus*)
在创建宏之前。
然后,在您使用它的命名空间中,执行
(binding [*bus* {:a "b"}]
...)
(注意 binding
是线程本地的。)
在这种情况下,我还会使用带有限定命名空间的 :as
快捷方式来引用 "helpers",以便更容易看到 *bus*
是在别处定义的。