有几种方法可以提供可选参数及其默认值。选择哪一个取决于您希望如何为函数调用提供这些可选参数。
严格的串行参数
您的参数已经按设置它们的可能性递减排序。您希望能够像这样调用函数(假设 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]