【发布时间】:2016-02-08 08:35:35
【问题描述】:
我正在尝试找到一种通过函数列表将值串接的方法。
首先,我有一个通常的基于环的代码:
(defn make-handler [routes]
(-> routes
(wrap-json-body)
(wrap-cors)
;; and so on
))
但这并不是最优的,因为我想编写一个测试来检查路由实际上是用 wrap-cors 包裹的。我决定将包装器提取到 def 中。于是代码变成了这样:
(def middleware
(list ('wrap-json-body)
('wrap-cors)
;; and so on
))
(defn make-handler [routes]
(-> routes middleware))
这显然不起作用,也不应该这样做,因为-> 宏不将列表作为第二个参数。所以我尝试使用apply 函数来解决这个问题:
(defn make-handler [routes]
(apply -> routes middleware))
最终通过:
CompilerException java.lang.RuntimeException: Can't take value of a 宏:#'clojure.core/->
那么问题来了:如何将值列表传递给-> 宏(或者说,任何其他宏),就像对函数使用apply 所做的那样?
【问题讨论】:
-
也许这是重复的,In clojure, how to apply a macro to a list? 回答了你的问题。
-
@sloth,感谢您指出这一点。虽然它提供了一些关于如何解决问题的想法,但我更喜欢 leetwinsky 的回答,因为它更符合我的口味,更符合我的口味。
-
->的主要目的是让代码更易于阅读。但是,如果您只是编写一个新宏以便可以使用->(在代码中您永远不会看到,因为它只存在于宏扩展中),我不明白这一点。本着从不使用函数的宏的精神,我建议以下解决方案:(reduce #(%2 %) routes middleware) -
@galdre 您的评论应该是公认的答案。