代码之家  ›  专栏  ›  技术社区  ›  Kai

带有可选标志的Clojure参数

  •  14
  • Kai  · 技术社区  · 15 年前

    实现关键字作为函数可选标志的最佳方法是什么?

    (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))
    
    4 回复  |  直到 15 年前
        1
  •  9
  •   achim    15 年前

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

    集合确实通过“包含”提供了基于值的快速查找,那么

    (defn foo [value & flags]
      (let [flags (set flags)]
        (if (contains? flags :add-one)
          (inc value)
          value)))
    

    如果没有多个标志,则可以使用如下分解:

    (defn foo [value & [flag]] …)
    
        2
  •  5
  •   pmf    15 年前

    clojure.contrib.def 包括 defnk

        3
  •  1
  •   Daniel Dinnyes    10 年前

    destructuring

    (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)
    

    precondition expressions 允许方便地测试参数,这也适用于解构键的值,如中所示 {:pre [...]}

    (myfunction "foo" :go-there true :do-this true :do-that false :times -1)
    
        4
  •  0
  •   Arthur Ulfeldt    15 年前

    严格地说,这不是写这篇文章最有效的方式,但很明显

    (defn myfunction [value & flags] 
      (cond (contains? (set flags) :a) 1
            (contains? (set flags) :b) 2)
    

    设置因子(设置标志)可能更有效。