11

假设我有一个 X.clojurescript 和一个 X.clojure 命名空间。X.clojurescript 中的所有内容都是 Clojurescript 代码,X.clojure 中的所有内容都是 Clojure 代码。不幸的是,我不能直接在 Clojurescript 中定义宏,我必须在 Clojure 中定义它们,然后使用

(ns X.clojurescript.abc
  (:require-macros [X.clojure.def :as clj]))

这可以。但是,如果宏(在 X.clojure 中定义)需要引用在 Clojurescript 命名空间(X.clojurescript)中定义的东西怎么办?问题是 Clojure 编译器在解析其他命名空间时不会查看我的 Clojurescript 命名空间(一个单独的目录)。

我通过简单地在我的 Clojure 代码中创建一个名称空间来解决这个问题,该名称空间与 Clojurescript 中存在的名称空间和所需定义相同,但这似乎有点愚蠢。因此,例如,如果我在宏中需要 X.clojurescript.abc.y,我将在 Clojure 端创建一个额外的命名空间,在我的 Clojure 版本的 X.clojurescript.abc 中定义一个虚拟 y;有点笨。

如何处理需要在 Clojurescript 端引用某些内容的宏?

4

1 回答 1

6

宏在定义时唯一需要特定命名空间的情况是,如果宏使用来自所述命名空间的代码来生成它将返回的符号列表。

您可以在 repl 中遵循这些示例:

(defmacro foo
  [a]
  `(bar/bar ~a))

即使 bar 不是定义的命名空间, foo 的定义也会编译

(foo :a)

现在调用 foo 将失败,因为您尚未定义 bar 命名空间或函数 bar

(ns bar)
(defn bar
  [x]
  [x x])

在 bar 命名空间中定义 bar

(ns user)
(foo :a)

=> [:a :a]

请注意,在 foo 定义时 bar 不需要存在。事实上,命名空间在 foo 定义时甚至不需要存在。

于 2013-05-13T13:56:05.097 回答