如何在函数调用中将显式args与变量args组合

bru*_*olf 1 clojure

在JavaScript中,可以执行以下操作:

function foo(arg1, arg2, arg3) {
  ...
}

var others = [ 'two', 'three' ];
foo('one', ...others);  // same as foo('one', 'two', 'three')
Run Code Online (Sandbox Code Playgroud)

在Clojure中,可以这样接受“变量args”:

function foo(arg1, arg2, arg3) {
  ...
}

var others = [ 'two', 'three' ];
foo('one', ...others);  // same as foo('one', 'two', 'three')
Run Code Online (Sandbox Code Playgroud)

但是要将它们与其他arg组合使用,您必须这样做:

(defn foo [arg1 & others]
  ...)
Run Code Online (Sandbox Code Playgroud)

坦白说,这真的很丑。当您需要重复执行操作时,这也是不可能的:

(apply foo (concat '("one") others))
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?如果不是,那么在这种recur情况下是否有任何方法可以实现?

Tay*_*ood 5

但是要将它们与其他arg组合使用,您必须这样做: (apply foo (concat '("one") others))

你不具备做:apply也是一个可变参数函数可以获取参数之前的最后序列参数如

(apply foo "one" others)
Run Code Online (Sandbox Code Playgroud)

您可以在最终序列参数之前将任意数量的单个参数传递给apply

user=> (defn foo [arg1 & args] (apply println arg1 args))
#'user/foo
user=> (apply foo "one" 2 "three" [4 "five" 6.0])
one 2 three 4 five 6.0
Run Code Online (Sandbox Code Playgroud)

为了进一步说明,这些对+功能的调用是等效的:

(apply + 1 2 [3])
(apply + 1 [2 3])
(apply + [1 2 3])
Run Code Online (Sandbox Code Playgroud)

当您需要做的是重复发生时,这也是不可能的

recur是一种特殊形式apply无法像典型的Clojure函数那样使用它。

在这种recur情况下,有什么办法可以实现?

不与apply。您可以recur使用可变参数args,但不能使用(apply recur ...)