具有可选标志的Clojure参数

Kai*_*Kai 14 parameters clojure keyword

将关键字作为可选标志实现到函数的最佳方法是什么?我想进行函数调用,例如:

(myfunction 5)
(myfunction 6 :do-this)
(myfunction 3 :go-here)
(myfunction 2 :do-this :do-that)
Run Code Online (Sandbox Code Playgroud)

使用defn,我可以定义一个函数,例如:

(defn myfunction [value & flags] ... )
Run Code Online (Sandbox Code Playgroud)

但这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))
Run Code Online (Sandbox Code Playgroud)

小智 9

列表(以及向量和映射)不是基于值的查找的数据结构的良好选择(将是线性时间),这就是为什么clojure.core没有这样的函数.

集合通过"contains?"提供快速的基于值的查找,那么怎么样

(defn foo [value & flags]
  (let [flags (set flags)]
    (if (contains? flags :add-one)
      (inc value)
      value)))
Run Code Online (Sandbox Code Playgroud)

如果没有多个标志,您可以使用这样的解构:

(defn foo [value & [flag]] …)
Run Code Online (Sandbox Code Playgroud)

  • 您可以将(包含?flags:add-one)缩写为(flags:add-one)或(:add-one flags). (3认同)
  • 如果你想要列表和向量的线性搜索,它在clojure.contrib.seq-utils/find-first中.如果您的列表只有几个项目,那么进行线性搜索可能比将其转换为集合更快.大多数情况下,您可能只会将少量参数传递给您的函数. (3认同)

pmf*_*pmf 5

clojure.contrib.def包括defnk-macro,它使用关键字参数定义函数更容易.