在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相当于关键字参数,看起来没有人引发标点炸弹?
答案 0 :(得分:98)
要更新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)
答案 1 :(得分:38)
在clojure中模拟关键字args的一种简单方法是在rest参数上使用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
中解释了我在上面显示的方法答案 2 :(得分:9)
clojure.contrib.def
最近添加了defnk
宏,可以使用关键字参数定义函数(请参阅here)。