Clojure 关键字参数

Posted

技术标签:

【中文标题】Clojure 关键字参数【英文标题】:Clojure keyword arguments 【发布时间】: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 你应该考虑更新接受的答案。 【参考方案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 中展示的方法

【讨论】:

见Alex Stoddard's answer;参数绑定中添加了对关键字 args 的支持。【参考方案3】:

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

【讨论】:

以上是关于Clojure 关键字参数的主要内容,如果未能解决你的问题,请参考以下文章

Clojure二分查找

Clojure按值获取映射键

如何在 Clojure 中递归展平任意嵌套的向量和映射?

Clojure线程优先具有过滤功能

为什么Clojure区分符号和变量?

Clojure 发布年度调查报告:用于开发企业软件的比例历史最高