我有一个宏将实现一个作为监听器的Java接口.我定义了宏来获取包含我想要解构的函数的映射,并用于每个接口方法.这是宏: -
(defmacro with-cache-listener-m [component event body]
(let [{:keys [f-insert f-update]} body]
`(. ~component addMapListener
(proxy [AbstractMapListener] []
(entryInserted [~event] ~f-insert ~event)
(entryUpdated [~event] ~f-update ~event)))))
Run Code Online (Sandbox Code Playgroud)
人体图是这样的: -
(def m-callbacks {:f-insert callback-insert :f-update callback-update})
Run Code Online (Sandbox Code Playgroud)
但是,当我打电话给(macroexpand '(with-cache-listener-m test-cache e m-callbacks))它扩展到(. test-cache user/addMapListener (clojure.core/proxy [com.tangosol.util.AbstractMapListener] [] (user/entryInserted [e] nil e) (user/entryUpdated [e] nil e)))
回调函数为零.我需要以不同的方式定义它们,还是以错误的方式解决这个问题.
当您调用with-cache-listener-m宏时,body参数会被限制为'm-callbacks符号,因此当您尝试解构该局部变量时,它将不起作用,因为它不是映射。您可以让生成的表单完成如下工作:
(defmacro with-cache-listener-m [component event body]
`(let [{:keys [f-insert# f-update#]} ~body]
(. ~component addMapListener
(proxy [AbstractMapListener] []
(entryInserted [~event] f-insert# ~event)
(entryUpdated [~event] f-update# ~event)))))
Run Code Online (Sandbox Code Playgroud)
但最后我不确定你的代码是否需要宏,你是否尝试将其编写为函数:
(defn add-map-listener [component insert-fn update-fn]
(.addMapListener component
(proxy [AbstractMapListener] []
(entryInserted [e] (insert-fn e))
(entryUpdated [e] (update-fn e)))))
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我改变了一些事情:
body在某种特殊上下文中评估某些代码( )的 with-* 宏。如果您想让这些功能完全可选并可以按任何顺序给出,您始终可以这样做:
(defn add-map-listener [component & functions]
(let [{:keys [insert-fn update-fn]} (into {} functions)]
(when-not (empty? functions)
(.addMapListener component
(proxy [AbstractMapListener] []
(entryInserted [e] (insert-fn e))
(entryUpdated [e] (update-fn e)))))))
Run Code Online (Sandbox Code Playgroud)
请注意,我添加了代码,以便在未给出函数时不调用 addMapListener。
| 归档时间: |
|
| 查看次数: |
742 次 |
| 最近记录: |