我对clojure非常陌生,我正在尝试在clojure函数中为args设置故障值。这是我到目前为止的内容:
(defn get-user-projects-by-user-id
([db-conn userid] (get-user-projects-by-user-id db-conn userid (str "asc") nil 10 10))
([db-conn userid sort filters offset size]
;;rest of the function
我要完成的工作是,只要该函数未收到排序,过滤器,偏移量或大小,或者为nil / false,它们分别获得默认值“ asc”,nil,10和10
但是,每当我不向用户ID发送任何这些参数到get-user-projects-by-id时,(println排序过滤器偏移量大小)为nil nil nil nil。
如何将它们设置为所需的默认值?
答案 0 :(得分:2)
在这里我可以想到3种方式:
您的版本:
(defn get-user-projects-by-user-id
([db-conn userid] (get-user-projects-by-user-id db-conn userid "asc" nil 10 10))
([db-conn userid sort filters offset size]
(println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))
;; (get-user-projects-by-user-id 'db 'userid)
;; => arguments: sort asc , filters nil , offset 10 , size 10
另一种样式是传递opts参数,该参数是带有所需选项的映射,您可以使用destructuring以方便的方式提供默认值:
(defn get-user-projects-by-user-id-with-opts
([db-conn userid]
(get-user-projects-by-user-id-with-opts db-conn userid nil))
([db-conn userid {:keys [sort filters offset size]
:or {sort "asc" offset 10 size 10}}]
(println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))
;; (get-user-projects-by-user-id-with-opts 'db 'userid)
;; => arguments: sort: asc filters: nil offset: 10 size: 10
;; (get-user-projects-by-user-id-with-opts 'db 'userid {:sort "desc" :offset 20})
;; => arguments: sort: desc filters: nil offset: 20 size: 10
最后,第三种方法有时在较旧的库中使用,该方法是将任意数量的参数传递给您的函数,并在其他参数之后采用可选参数(我想这有点像Python):< / p>
(defn get-user-projects-by-user-id-with-varargs
[db-conn userid & args]
(let [arg-map (apply hash-map args)
{:keys [sort filters offset size]
:or {sort "asc" offset 10 size 10}} arg-map]
(println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))
;; (get-user-projects-by-user-id-with-varargs 'db 'userid)
;; => arguments: sort: asc filters: nil offset: 10 size: 10
;; (get-user-projects-by-user-id-with-varargs 'db 'userid :sort "desc" :offset 20)
;; => arguments: sort: desc filters: nil offset: 20 size: 10
答案 1 :(得分:0)
有几种提供可选参数及其默认值的方法。选择哪个取决于您要如何向函数调用提供那些可选参数。
您的参数已经通过减小设置参数的可能性进行了排序。您希望能够像这样调用该函数(假设一个println
函数体而忽略了nil
返回值):
user> (get-user-projects-by-user-id :conn :uid)
[:conn :uid asc nil 10 10]
user> (get-user-projects-by-user-id :conn :uid :sort)
[:conn :uid :sort nil 10 10]
user> (get-user-projects-by-user-id :conn :uid :sort "filter")
[:conn :uid :sort filter 10 10]
user> (get-user-projects-by-user-id :conn :uid :sort "filter" 9)
[:conn :uid :sort filter 9 10]
为此,您可以通过已启动的Arity重载该功能:
(defn get-user-projects-by-user-id
([db-conn userid]
(get-user-projects-by-user-id db-conn userid
(str "asc")
nil
10
10))
([db-conn userid sort]
(get-user-projects-by-user-id db-conn userid
sort
nil
10
10))
([db-conn userid sort filters]
(get-user-projects-by-user-id db-conn userid
sort
filters
10
10))
([db-conn userid sort filters offset]
(get-user-projects-by-user-id db-conn userid
sort
filters
offset
10))
([db-conn userid sort filters offset size]
(println [db-conn userid sort filters offset size])))
函数定义有点繁琐,在重构时必须小心以保持默认值正确。
您可以在参数向量中使用 destructuring 来允许传递带有额外参数的地图。这允许以任何顺序传递它们:您可以覆盖offset
,而不必传递sort
和其他变量:
(defn get-user-projects-by-user-id-extra-map
[db-conn userid & [{:keys [sort filters offset size]
:or {sort "asc"
filters nil
offset 10
size 10}}]]
(println [db-conn userid sort filters offset size]))
您可以这样使用它:
user> (get-user-projects-by-user-id-extra-map :conn :uid {:offset 9})
[:conn :uid asc nil 9 10]
如果您稍微修改解构结构(请注意缺少的[]
),则可以无需映射就将可选参数作为键值对传递。当您的函数调用都是显式的时,这通常更容易使用,而当您apply
以编程方式收集的额外参数来使用函数时,上一个选项通常会更容易。
(defn get-user-projects-by-user-id-pairs
[db-conn userid & {:keys [sort filters offset size]
:or {sort "asc"
filters nil
offset 10
size 10}}]
(println [db-conn userid sort filters offset size]))
使用它(注意缺少{}
):
user> (get-user-projects-by-user-id-pairs :conn :uid :offset 9)
[:conn :uid asc nil 9 10]