如何忽略不必要的论点?

bou*_*ekv 10 clojure

是否有简单的方法可以忽略不必要的参数?

例如: (#(+ %1 %2) 1 2)返回3

我想强制这个代码

(#(+ %1 %2) 1 2 3)
Run Code Online (Sandbox Code Playgroud)

也返回3.但它回来了

java.lang.IllegalArgumentException:传递给的args(3)数量错误.

怎么改#(+ %1 %2)

我希望有一些更优雅的方式#(+ (nth %& 0) (nth %& 1)).

Omr*_*ein 18

这就是我要去的地方:

=> ((fn [a b & _] (+ a b)) 1 2 3)
=> 3
Run Code Online (Sandbox Code Playgroud)

这会创建一个带有任意数量参数的匿名函数,但只添加前两个.这个_符号并没有做任何特别的事情,它只是惯用于"我不关心这件事,但我需要它以某种方式绑定".如果你认为你将要做很多事情,那么你可能想要定义它:

(defn add-first-two
  [a b & _]
  (+ a b))
Run Code Online (Sandbox Code Playgroud)

如果您真的使用了#()语法,则必须%&在定义中包含某些内容以"实现"它应该采用任意数量的参数.这并不意味着您必须在显示时对其进行索引,它只需要存在于某处.这是一个例子:

=> (#(do %& (+ %1 %2)) 1 2 3)
=> 3
Run Code Online (Sandbox Code Playgroud)

另一方面,这个解决方案涉及某种处理%&,你不需要任何处理,并且可能会稍微放慢速度(我不确定这个,也许其他人可以给我反馈).一个相当有趣的解决方案就是坚持%&一个(comment ...)块,它将评估为nil.

=> (#(do (comment %&) (+ %1 %2)) 1 2 3)
=> 3
Run Code Online (Sandbox Code Playgroud)

一个更奇特的解决方案就是使用#_...,(comment...)除了读者实际上将它从评估中删除之外,这很像,就好像你只是在那里输入任何东西一样.这样,也许我们可以将它粘在体内(+ ...)以缩短代码.

=> (#(+ %1 %2 #_%&) 1 2 3)
=> 3
Run Code Online (Sandbox Code Playgroud)

你知道什么,它有效.我以前从未尝试过这个,我很惊讶它看起来有用.显然,在#_...删除该部分之前有一些处理.奇怪.

如果您不喜欢这些奇怪的评论解决方案,并且do不是为您做的,您可以随时将其放在一个(if nil ...)块中:

=> (#(if nil %& (+ %1 %2)) 1 2 3)
=> 3
Run Code Online (Sandbox Code Playgroud)

好吧,毕竟,我仍然喜欢第一个最好的解决方案(使用(fn ...)),但其中一些肯定更短.


Ger*_*ert 5

这适用于任意数量的参数,并且可读:

(fn [& args] (apply + args))
Run Code Online (Sandbox Code Playgroud)

如果你只想使用前两个参数(根据Alex的评论):

(fn [& args] (apply + (take 2 args)))
Run Code Online (Sandbox Code Playgroud)

您可以直接使用它:

((fn [& args] (apply + (take 2 args))) 1 2)
; => 3
Run Code Online (Sandbox Code Playgroud)

或者将函数绑定到这样的符号:

(let [f (fn [& args] (apply + (take 2 args)))]
  (f 1 2))
; => 3
Run Code Online (Sandbox Code Playgroud)

或者创建一个var:

(def f (fn [& args] (apply + (take 2 args))))
Run Code Online (Sandbox Code Playgroud)

或功能:

(defn f [& args] (apply + (take 2 args)))
Run Code Online (Sandbox Code Playgroud)

最佳定义取决于您的用例.

  • 这是对所有论点的总结.OP要求前两个的总和,忽略任何额外的东西,所以你不得不说(fn [&args](申请+(拿2个args))) (2认同)