如何使 Clojure 函数采用可变数量的参数?

Posted

技术标签:

【中文标题】如何使 Clojure 函数采用可变数量的参数?【英文标题】:How to make a Clojure function take a variable number of parameters? 【发布时间】:2012-03-03 18:54:12 【问题描述】:

我正在学习 Clojure,我正在尝试定义一个函数,该函数采用可变数量的参数(一个 variadic 函数)并将它们相加(是的,就像 + 过程一样)。但是,我不知道如何实现这样的功能

我能做的就是:

(defn sum [n1, n2] (+ n1 n2))

当然,这个函数需要两个参数和两个参数。请教我如何让它接受(和处理)未定义数量的参数。

【问题讨论】:

【参考方案1】:

一般情况下,您可以使用apply:

(defn sum [& args] (apply + args))

由于加法是可交换的,这样的事情也应该起作用:

(defn sum [& args] (reduce + args))

& 导致args 绑定到参数列表的其余部分(在本例中是整个列表,因为& 左侧没有任何内容)。

显然这样定义 sum 没有意义,因为不是:

(sum a b c d e ...)

你可以写:

(+ a b c d e ....)

【讨论】:

是的,没有意义,但它很好地说明了您的答案。谢谢。 @soulcheck:有没有办法将 seq 传递给您的 sum 函数。例如: (sum '(1 2 3)) 结果是 6 ? @avichalp 这将是另一个功能。只需从任一版本中删除 & @soulcheck:不。我的意思是使用相同的函数签名。我是clojure的新手,因此我可以在这里清楚地表达我的观点。我想知道的是在python中我可以使用*args,如果一个函数被定义为它需要*args(例如def fn(*args): pass),我可以通过给出一个像fn(*list_of_args)这样的列表来调用它。我可以在 clojure 中做同样的事情吗? @avichalp 对def fn(*args): pass 的调用不会是fn([1,2,3]),而是fn(1,2,3)(显然取决于你想要做什么,但我正在努力追随这里的精神)跨度> 【参考方案2】:

Yehoanathan 提到了 arity 重载,但没有提供直接示例。以下是他所说的:

(defn special-sum
  ([] (+ 10 10))
  ([x] (+ 10 x))
  ([x y] (+ x y)))

(special-sum) => 20

(special-sum 50) => 60

(special-sum 50 25) => 75

【讨论】:

也适用于 lambda:(fn ([] (+ 10 10)) ([x] (+ 10 x)) ([x y] (+ x y)))【参考方案3】:
 (defn my-sum
  ([]  0)                         ; no parameter
  ([x] x)                         ; one parameter
  ([x y] (+ x y))                 ; two parameters
  ([x y & more]                   ; more than two parameters


    (reduce + (my-sum x y) more))
  )

【讨论】:

【参考方案4】:

defn 是一个宏,它使定义函数更简单一些。 Clojure 支持在单个函数对象中重载 arity, 使用&的自引用和可变参数函数

来自http://clojure.org/functional_programming

【讨论】:

【参考方案5】:
(defn sum [& args]
  (print "sum of" args ":" (apply + args)))

这需要任意数量的参数并将它们相加。

【讨论】:

重复@soulcheck 答案***.com/a/9242671/1327651

以上是关于如何使 Clojure 函数采用可变数量的参数?的主要内容,如果未能解决你的问题,请参考以下文章

C++11:可变参数模板函数参数的数量?

如何使用可变参数模板参数保存可变数量的参数?

C语言中如何实现可变参函数

C:将可变数量的参数从一个函数传递到另一个函数

C 中 printf() 函数的工作(仅可变数量的参数)

python中定义函数时如何书写可变参数和默认参数