【问题标题】:Clojure keyword argumentsClojure 关键字参数
【发布时间】:2010-10-17 14:33:39
【问题描述】:

在 Common Lisp 中你可以这样做:

(defun foo (bar &key baz quux)
  (list bar baz quux))

(foo 1 :quux 3 :baz 2) ; => (1 2 3)

Clojure 没有关键字参数。一种替代方法是:

(defn foo [bar {:keys [baz quux]}] 
  (list bar baz quux))

(foo 1 {:quux 3 :baz 2}) ; => (1 2 3)

嵌套的括号太多,不得不一直输入和阅读。它还需要一个显式的哈希映射作为参数而不是平面列表传入。

什么是最惯用的 Clojure 等效关键字参数,看起来不像有人引爆了标点符号?

【问题讨论】:

  • 自从这个问题是最后一个活跃的关键字解构绑定已添加到 Clojure。我已经提供了一个答案来表明这一点。
  • @Brian 你应该考虑更新接受的答案。

标签: binding clojure lisp common-lisp params-keyword


【解决方案1】:

为了更新 Clojure 1.2 的这个答案,现在有完整的关键字 arg 支持,默认值由 destructuring binding 的映射形式提供:

user> (defn foo [bar &{ :keys [baz quux] 
                        :or {baz "baz_default" quux "quux_default"}}]
         (list bar baz quux))
#'user/foo

user> (foo 1 :quux 3)
(1 "baz_default" 3)

【讨论】:

  • 我认为这应该被提升为答案?
【解决方案2】:

在 clojure 中模拟关键字 args 的一种简单方法是在其余参数上使用 hash-map,如下所示:

> (defn kwtest [x & e] (:foo (apply hash-map e)))
#'user/kwtest
> (kwtest 12 :bar "ignored" :foo "returned")
"returned"

Rich Hickey 在this message from the clojure google group 中提供了一个宏,它为您提供关键字参数。 corresponding thread 包含有关为什么 clojure 不支持关键字参数的信息。基本上是为了避免运行时开销。 Rich 解释了我上面在this message 中展示的方法

【讨论】:

【解决方案3】:

clojure.contrib.def 的最新新增功能是defnk 宏,它可以使用关键字参数定义函数(请参阅here)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多