有没有办法在clojure中避免这种重复的代码?

时间:2014-04-19 01:46:18

标签: clojure

我得到了一些参数然后调用一个接受参数映射的函数。 地图的关键名称是params的名称,如下所示:

   (GET "/api/search" [nick_name gender phone max_age min_age page lmt ]
        (db-search-users :nick_name nick_name :gender gender :phone phone
:max_age max_age :min_age min_age :page page :lmt lmt))

有什么方法可以避免复制和粘贴吗?

2 个答案:

答案 0 :(得分:7)

我认为你使用的是Compojure?你不需要对参数图进行解构(Compojure中的向量是{:keys [...]}的简写 - 就像参数图上的解构一样),你可以简单地将它传递给你的函数:

;; you can use a map to destructure the entire request map
(GET "/api/search" {:keys [params]}
  (db-search-users (select-keys params [:nick_name ...])))

select-keys是可选的,但如果没有它,您的功能可能最终会在地图中收到意外的密钥。

您可能需要考虑验证params - 可能会将某些值强制转换为更有用的类型 - 然后再将其传递给db-search-users。请参阅Prismatic的schema以获得一个很好的方法。

答案 1 :(得分:2)

让宏为您完成工作:

(defmacro make-get [path & keywords]
  `(GET ~path [~@keywords]
        (db-search-users ~@(flatten (map #(list (keyword %) %) keywords)))))

用法:

(macroexpand-1 '(make-get "/api/search" nick_name gender phone max_age min_age page lmt))
(user/GET "/api/search" [nick_name gender phone max_age min_age page lmt] (user/db-search-users :nick_name nick_name :gender gender :phone phone :max_age max_age :min_age min_age :page page :lmt lmt))