我可以定义一个函数,其中主体是 clojure 中的引用主体吗?

时间:2020-12-28 10:48:28

标签: clojure

所以,这就是我想做的

(def body `(prn sth))
(defn f [sth] body)

(f "hello")
; can it prn hello here?

这可能吗?

1 个答案:

答案 0 :(得分:3)

如果你想“把一个数据结构嵌入到要执行的代码中”,那么你可以这样做。

您需要像这样调整正文以嵌入:

(def body `(prn ~'sth))

也就是说,在 sth 局部变量前加上 ~' 使其不会被命名空间。然后你需要一个宏来为你嵌入代码:

(defmacro insert-body [body]
  (eval body))

f 函数中使用这个宏来嵌入主体并将内容放在一起,您会得到以下代码:

(defmacro insert-body [body]
  (eval body))

(def body `(prn ~'sth))
(defn f [sth] (insert-body body))

您现在可以使用参数调用 f,它会按预期工作:

> (f "hello")
"hello"
nil

函数 macroexpand 可以派上用场来测试宏是否完成了它应该做的事情:

(macroexpand `(insert-body body))
;; => (clojure.core/prn sth)

但是我不清楚您想要完成什么,或者您会从这种方式编写代码中获得什么。无论您最终想完成什么,很可能有比我在这里建议的更好的方法来完成它。我只是为你的问题提供一个具体的答案,仅此而已。因此,如果您澄清您的问题并提供更多详细信息,也可以提供更好的答案来解决您的实际问题。