Clojure变量函数,多绑定
举个例子:Clojure变量函数,多绑定,clojure,variadic-functions,Clojure,Variadic Functions,举个例子: (defn foo[a和[b c:as args]](prn args)) 有没有办法在b和c之后添加第四个可选参数 我尝试了这个和其他一些变体,但没有成功(compilereException java.lang.RuntimeException:Unexpected参数): (defn foo[a和[b c:as args d]](prn d)) …另一个示例(compilereException java.lang.RuntimeException:无法在此上下文中解析符号:d
(defn foo[a和[b c:as args]](prn args))
有没有办法在b
和c
之后添加第四个可选参数
我尝试了这个和其他一些变体,但没有成功(compilereException java.lang.RuntimeException:Unexpected参数
):
(defn foo[a和[b c:as args d]](prn d))
…另一个示例(compilereException java.lang.RuntimeException:无法在此上下文中解析符号:d
)
(defn foo[a和[b c:as args&d]](prn d))
如果要添加更多参数,是否在:as args
之后使用hosed
编辑:这是在IRC中建议的,它是有效的,我只是想知道是否有一种语法上更简单的方法
(defn foo[a&rst](let[[b c&d]rst args[b c]]{:a:b b b c:args args:rst rst})
(defn foo[a和[b c d:as args]](prn args))
您无法通过进一步解构来控制已解构rest序列中的元素数量
例如
绑定第一个元素没有区别。这与绑定向量是[a&args]
的情况相同,只是您通过进一步解构args
的前两个元素(b
和c
)进行了额外绑定。它不受它的影响
如果您需要args
仅包含前两个可变args,b
和c
,并且希望将第三个绑定为可选的d
,则一种方法是:
(defn foo [a & [b c d :as args]]
(let [args (seq (take 2 args))]
;; ...
))
如果这对(b,c)有一种特殊的关系,为什么不把它们放在一个嵌套的向量中呢?这将允许为它定义一个特定的绑定(但在输入上添加一个约束),例如
然后:
当您输入向量[bc]
时,您将获得带有参数的绑定:
> (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)}
但是现在d
是args
的一部分,这不是我想要的。我希望能够将b
和c
绑定到一件事上,将d
绑定到另一件事上。有人在IRC中建议了这一点:(defn foo[a&rst](let[[b c&d]rst args[b c]]{:a:b:c:args args:rst rst rst}),这是可行的,但要复杂一些=)
> (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)}