如何使 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 函数采用可变数量的参数?的主要内容,如果未能解决你的问题,请参考以下文章