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

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

我能做的就是:

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

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

【问题讨论】:

    标签: function clojure lisp procedure


    【解决方案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)))
        

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

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多