0
我Clojure的应用程序需要一些处理做生意,这些处理器将瓶坯一些常用的参数检查,所以我使用宏来做到这一点象下面这样:如何做出正确的FN ARGS当创建FN使用宏
(defmacro defapihandler [handler-name params & body]
`(defn ~handler-name ~params
(let [keyed-params# (map keyword '~params)
checked-ret# (check-param (zipmap keyed-params# ~params))]
(if (:is-ok checked-ret#)
(do [email protected])
(-> (response {:code 10000
:msg (format " %s are missing !!!" (:missed-params checked-ret#))})
(status 400))))))
然后我可以像这样使用上面的宏:
(defapihandler create-user [username password birthday]
;; todo
)
这样一切都很好。
正如您所看到的,生成的fn的参数直接由marco的args构造,异常在生成的fn的params无法直接构建时引发。
拿一个例子:
宏观defapihandler
的params
现在成了这个样子:
[{:key :username :checker [not-nil?]} {:key :password :checkers [is-secure?]} ...]
在宏,我想建立的产生FN帕拉姆动态地是这样的:
(defmacro defapihandler [handler-name params & body]
`(defn ~handler-name [passed-param#]
(let [param-keys# (vec (map (comp symbol name :key)
~params))
{:keys param-keys#} passed-param#]
;; some check
(do [email protected]))))
(defapihandler create-user [{:key :username :checkers []}]
(println username))
passed-param
的结构看起来像这样:{:username "foo" :password "bar"}
现在我要构建let
块body
块中使用的变量,那么下面的异常被抛出:
Caused by java.lang.IllegalArgumentException
Don't know how to create ISeq from: clojure.lang.Symbol
macroexpand
create-user
得到这个:
(defn create-user [passed-param__10243__auto__]
(let [param-keys__10244__auto__ (vec
(map
(comp symbol name :key)
[{:key :username,
:checkers []}]))
{:keys param-keys__10244__auto__} passed-param__10243__auto__]
(do (println username))))
我怀疑这异常有关动态变量用于让解构形式,如果我的嫌疑人是正确的,那么如何构造body
块中使用的变量?
你的代码做的工作,但我仍然很困惑为什么要使用'[]'从字面上看,我的代码将尝试将'param-keys#'作为'Symbol'解析为'Symbol'而不是'ISeq',如异常所述 –
参数向量或'let'子句左侧的符号未解析。例如,'(let [x'a,x 2] x)'。在这里,“x”将首先设置为符号“a”,然后“x”将设置为“2”。你不会发现'x'是'a','a'是'2'。 – weavejester