【问题标题】:Clojure: How to Preserve Variadic Args Between Function CallsClojure:如何在函数调用之间保留可变参数
【发布时间】:2025-11-21 10:40:02
【问题描述】:

我有两个可变参数函数。其中一个将其论点传递给另一个。问题是可变参数正在成为第二次调用的列表。如何让它们保持可变参数?

=> (defn foo [x & ys] (println x ys))
=> (defn bar [x & ys] (foo (clojure.string/upper-case x) ys))
=> (foo "hi")  
hi nil
=> (bar "hi")
HI (nil)

在真正的函数中,foo 将它的 args 传递给一个可变参数的 java 函数,所以 varargs 确实需要保持 varargs。我该怎么做?

【问题讨论】:

  • 你在这里问什么与你刚才问的另一个问题不同,*.com/q/26021785/1756702
  • 是的,apply 也是这里的答案。你会想要into-array 来调用Java 方法(varargs 是Java 编译器的东西,Clojure 不使用Java 编译器,在jvm 中它只使用一个数组作为最后一个arg)
  • 这样的? (apply identity ys) 我想按原样传递它们,所以我认为这与我提出的关于转换它们但保持可变参数的问题有点不同,那是在一个函数中。
  • 我在bar 中尝试了(apply identity ys),但我得到了这个ArityException Wrong number of args (0) passed to: core/identity clojure.lang.AFn.throwArity (AFn.java:429)
  • Java 可变参数一个数组。这就是他们曾经的全部。 Java 中的可变参数永远不可能是非数组的东西。 “让它们保持可变参数”不是一个有意义的问题,因为 它们只不过是一个数组(Java 编译器中有一点语法糖,Clojure 编译器不提供或尊重) 首先

标签: clojure variadic-functions


【解决方案1】:

来自http://clojuredocs.org/clojure_core/clojure.core/apply

;您也可以将操作数放在操作数列表之前,它们将是 在操作数列表中消耗 (apply + 1 2 '(3 4)) ;等于 (应用+'(1 2 3 4)) => 10

所以

(defn bar [x & ys] (apply foo (clojure.string/upper-case x) ys))

应该可以。 对于 Java varargs 的问题,请注意 noisesmith 的评论。

【讨论】: