Clojure可变参数函数,多重绑定

时间:2015-04-10 15:33:34

标签: clojure variadic-functions

给出这个例子:

(defn foo [a & [b c :as args]](prn args))

有什么办法可以在bc之后添加第四个可选参数吗?

我已经尝试了这个以及其他一些变体而没有成功(CompilerException java.lang.RuntimeException: Unexpected parameter):

(defn foo [a & [b c :as args d]](prn d))

..另一个例子(CompilerException java.lang.RuntimeException: Unable to resolve symbol: d in this context

(defn foo [a & [b c :as args & d]](prn d))

如果我想添加更多参数,我是否在:as args之后进行了冲洗?

编辑:这是在IRC中提出的,它有效,我只是想知道是否有一种语法更简单的方法......

(defn foo [a & rst] (let [[b c & d] rst args [b c]] {:a a :b b c :args args :rst rst}))

3 个答案:

答案 0 :(得分:2)

如果对(b,c)有特殊关系,为什么不将它们放在嵌套向量[]中?这将允许为它定义一个特定的绑定(但在输入上添加一个约束),例如

(defn bar [a & [[b c :as args] & rest :as all]]
  {:a a :b b :c c :args args :rest rest :all all})

然后:

> (bar 1)
{:a 1, :b nil, :c nil, :args nil, :rest nil, :all nil}

当您输入向量[b c]时,您将获得与args的绑定:

> (bar 1 [2 3])
{:a 1, :b 2, :c 3, :args [2 3], :rest nil, :all ([2 3])}

你可以拥有一个带有一个元素的向量

> (bar 1 [2] 4)
{:a 1, :b 2, :c nil, :args [2], :rest (4), :all ([2] 4)}

或根本没有元素

> (bar 1 [] 4 5 6)
{:a 1, :b nil, :c nil, :args [], :rest (4 5 6), :all ([] 4 5 6)}

并设置所有参数

> (bar 1 [2 3] 4 5 6)
{:a 1, :b 2, :c 3, :args [2 3], :rest (4 5 6), :all ([2 3] 4 5 6)}

答案 1 :(得分:1)

您无法通过进一步对其进行析构来控制解构后的休息序列中的元素数量。

电子。克。

(defn foo [a & [b c :as args]] args)
(foo 1 2 3 4 5)
;; => (2 3 4 5)

绑定第一个元素没有区别。它与绑定向量为[a & args]的情况相同,只是通过进一步对其进行析构而另外绑定b的前两个元素(cargs)。它不受它的影响。

如果您需要args只拥有前两个可变参数bc,并希望将第三个绑定为可选d,那么:

(defn foo [a & [b c d :as args]]
  (let [args (seq (take 2 args))]
    ;; ...
    ))

答案 2 :(得分:0)

(defn foo [a & [b c d :as args]](prn args))