8

我是 Clojure 的新手,我想知道是否有一种方法可以定义一个可以像这样调用的函数:

(strange-adder 1 2 3 :strange true)

也就是说,一个可以接收可变数量的整数和关键字参数的函数。

我知道我可以这样定义一个带有关键字参数的函数:

(defn strange-adder
  [a b c & {:keys [strange]}]
  (println strange)
  (+ a b c))

但是现在我的函数只能接收固定数量的整数。

有没有办法同时使用这两种风格?

4

3 回答 3

10

抱歉不行。

解构运算符在参数列表中使用它之后的&所有内容,因此它无法以一种形式处理两组不同的可变数量解构组。

一种选择是将函数分解为几个元素。尽管这仅在您可以安排它时才有效,因此只有其中一个是可变参数(使用&)。一个更通用且不太方便的解决方案是将整个参数列表视为一种可变参数形式,并手动从它的开头挑选数字。

user> (defn strange-adder
        [& args]
         (let [nums (take-while number? args)
               opts (apply hash-map (drop-while number? args))
               strange (:strange opts)]
          (println strange)
              (apply + nums)))
#'user/strange-adder
user> (strange-adder 1 2 3 4 :strange 4)
4
10
于 2013-08-26T17:20:24.463 回答
4

将可变参数部分移动到参数列表的尾部,并将选项作为映射传递:

(defn strange-adder [{:keys [strange]} & nums] 
  (println strange) 
  (apply + nums))

(strange-adder {:strange true} 1 2 3 4 5)
于 2013-08-26T17:37:02.093 回答
1

据我所知,没有正式的支持,但这样的事情应该是可行的:

(defn strange-adder
  [& args]
  (if (#{:strange} (-> args butlast last))
    (do (println (last args))
        (apply + (drop-last 2 args)))
    (apply + args)))

我不知道这是否可以概括(检查关键字?如何扩展到任意数量的最终参数?)。一个选项可能是将所有选项作为最后一个参数放在哈希图中,并检查最后一个参数是否是哈希图(但这对于某些期望可能是哈希图的任意参数的函数不起作用)。

于 2013-08-26T17:35:46.403 回答