与可选的标志参数的Clojure
-
20-08-2019 - |
题
什么是执行的关键字,可选的标志给函数的最佳方式? 我想使函数调用,例如:
(myfunction 5)
(myfunction 6 :do-this)
(myfunction 3 :go-here)
(myfunction 2 :do-this :do-that)
使用DEFN,我可以定义一个函数,例如:
(defn myfunction [value & flags] ... )
但flags
变为列表。我可以写我自己的函数来搜索列表,但不包括在核心库这样的功能,所以我认为它不是地道的。
我现在使用什么:
(defn flag-set? [list flag] (not (empty? (filter #(= flag %) list))))
(defn flag-add [list flag] (cons flag list))
(defn flag-remove [list flag] (filter #(not= flag %) list))
解决方案
列表(以及载体和地图)不是数据结构的对基于值的查找一个很好的选择(将是线性的时间),这就是为什么clojure.core不具有这样的功能。
设定做提供快速的基于价值的查找经“载?”,所以怎么样
(defn foo [value & flags]
(let [flags (set flags)]
(if (contains? flags :add-one)
(inc value)
value)))
如果都不会有超过一个标志,你可以用解构这样的:
(defn foo [value & [flag]] …)
其他提示
clojure.contrib.def
包括defnk
宏,这使得定义函数以关键字参数更容易。
可以使用哈希地图为解构结合一>这样的可选参数:
(defn myfunction
[value & {:keys [go-there do-this do-that times] :or {times 1}}]
{:pre [(integer? times) (< 0 times)]}
(println "Saw a" value)
(when go-there
(dotimes [n times]
(when do-this (println "Did THIS with" value))
(when do-that (println "Did THAT with" value)))))
上述功能可以被称为以下方式:
(myfunction "foo" :go-there true :do-this true :do-that false :times 5)
注意,可以用于与:or {times 1}
子句键定义的默认值。下面的函数调用将仅循环一次由于该默认:
(myfunction "foo" :go-there true :do-this true :do-that false)
此外,Clojure的前提表达式允许的参数测试方便,它适用于在解构后的值键也一样,它可以在{:pre [...]}
表达的参数绑定之后看到。由于该先决条件检查下面的调用将失败:
(myfunction "foo" :go-there true :do-this true :do-that false :times -1)
这是严格来说不是写这个的最有效的方法,但很显然
(defn myfunction [value & flags] (cond (contains? (set flags) :a) 1 (contains? (set flags) :b) 2)
它可能是更有效的因子(组标志)向上。
不隶属于 StackOverflow