clojure - 我可以定义一个函数,其中主体是 clojure 中的引用主体吗?
问题描述
所以,这就是我想做的
(def body `(prn sth))
(defn f [sth] body)
(f "hello")
; can it prn hello here?
这可能吗?
解决方案
如果你想“获取一个数据结构并将其嵌入到要执行的代码中”,那么你可以做这样的事情。
您将需要像这样调整主体以嵌入:
(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)
但我不清楚您要完成什么或以这种方式编写代码会获得什么。无论您最终想要完成什么,很可能有比我在这里建议的更好的方法来完成它。我只是为您的问题提供一个具体的答案,仅此而已。因此,如果您澄清您的问题并提供更多详细信息,也可以提供更好的答案来解决您的实际问题。
推荐阅读
- maven - 覆盖 Apache Maven 依赖插件的设置
- java - 使用给定的 JUNIT 测试在数组中找到最接近平均值的值
- timer - 在触发回调nodemcu之前删除计时器警报
- php - 让我们在 LEMP Ubuntu 16.04 上使用 Nginx 加密 Laravel 应用程序
- java - Java Futures 在使用 Mockito 时返回 null
- c++ - 模板模板参数中模板参数数量不匹配
- python - Zeppelin & spark.ipyspark & folium
- python - 按下按钮时退出while循环
- python - Tkinter 窗口未从线程打开,使用来自套接字连接的数据
- javascript - react-input-range 不会在 react-leaflet Map 中触发事件(onChange,onClick)