Binding Clojure关键字参数

Binding Clojure关键字参数,binding,clojure,lisp,common-lisp,params-keyword,Binding,Clojure,Lisp,Common Lisp,Params Keyword,在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) 这是

在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中模拟关键字参数的一种简单方法是对rest参数使用哈希映射,如下所示:

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

Rich Hickey在中提供了一个宏,可以为您提供关键字参数。包含有关clojure不支持关键字参数的原因的信息。基本上是为了避免运行时开销。Rich解释了我在上面的
clojure.contrib.def
中所展示的方法,最近添加了
defnk
宏,该宏支持使用关键字参数定义函数(请参见)。

要更新clojure 1.2的此答案,现在有了完整的关键字arg支持,默认值由以下映射形式提供:


因为这个问题是上次激活的关键字,所以解构绑定已经添加到Clojure中。我已经提供了一个答案来表明这一点。“布瑞恩,你应该考虑更新所接受的答案。我认为这应该被提升为答案。”对关键字args的支持已添加到参数绑定中。
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)