首页 > 解决方案 > 我可以定义一个函数,其中主体是 clojure 中的引用主体吗?

问题描述

所以,这就是我想做的

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

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

这可能吗?

标签: clojure

解决方案


如果你想“获取一个数据结构并将其嵌入到要执行的代码中”,那么你可以做这样的事情。

您将需要像这样调整主体以嵌入:

(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)

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


推荐阅读