用不同数量的参数重载的函数 [英] functions overloaded with different number of arguments

查看:31
本文介绍了用不同数量的参数重载的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

许多 Clo​​jure 函数接受不同数量的参数,我经常对文档及其与我应该使用函数的方式的关系感到困惑.

A lot of the Clojure functions accept various number of arguments and I'm often a bit confused by the documentation and how it relates to the way I should be using the function.

例如 (doc partial) 返回这个:

([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more])

我的问题不是专门关于部分而是...

My question is not specifically about partial but...

为什么最多 arg1 arg2 arg3 &更多 而不是 arg1 &更多arg1 arg2 &更多arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 &更多?

Why up to arg1 arg2 arg3 & more and not arg1 & more or arg1 arg2 & more or arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 & more ?

我对最后一个很滑稽,但这是一个非常现实的问题:是什么决定了需要在 & 之前放置多少个argX"?更多?

I'm being facetious with the last one but this is a very real question: what determines how many "argX" one needs to put before the & more?

推荐答案

以下答案是我的猜测:看一下 partial 的实现向我们展示:

The following answer is a guess on my part: A look at the implementation of partial show us:

(defn partial
  "Takes a function f and fewer than the normal arguments to f, and
  returns a fn that takes a variable number of additional args. When
  called, the returned function calls f with args + additional args."
  {:added "1.0"
   :static true}
  ([f arg1]
   (fn [& args] (apply f arg1 args)))
  ([f arg1 arg2]
   (fn [& args] (apply f arg1 arg2 args)))
  ([f arg1 arg2 arg3]
   (fn [& args] (apply f arg1 arg2 arg3 args)))
  ([f arg1 arg2 arg3 & more]
   (fn [& args] (apply f arg1 arg2 arg3 (concat more args)))))

如您所见,对partial 的每次调用都在做同样的事情——即返回一个函数,该函数接受一些参数并使用输入参数和新参数调用输入函数的apply.所以这确实可以写成 arg1 &更多.但是等等,让我们看看 apply 的实现:

As you can see, every call to partial is doing the same thing - namely, returning a function which accepts some args and calls apply on the input function with input args and new args. So this could indeed have been written as arg1 & more. But wait, lets look at the implementation of apply as well:

(defn apply
 "Applies fn f to the argument list formed by prepending intervening arguments to args."
 {:added "1.0"
  :static true}
 ([^clojure.lang.IFn f args]
    (. f (applyTo (seq args))))
 ([^clojure.lang.IFn f x args]
    (. f (applyTo (list* x args))))
 ([^clojure.lang.IFn f x y args]
    (. f (applyTo (list* x y args))))
 ([^clojure.lang.IFn f x y z args]
    (. f (applyTo (list* x y z args))))
 ([^clojure.lang.IFn f a b c d & args]
    (. f (applyTo (cons a (cons b (cons c (cons d (spread args)))))))))

Apply 是一个核心函数,当给定不同数量的参数时,它的执行方式不同.这是出于性能原因而应用的优化.这就是暴露部分(和其他此类函数)的不同参数的原因,因为代码的内部执行对于不同的参数是不同的.

Apply is a core function, and it is executes differently when given a different number of arguments. This is an optimization to apply for performance reasons. This is the reason for exposing different arities of partial (and other such functions), because the internal execution of the code differs for different arities.

我假设 clojure/core 团队认为暴露部分超出 arg1 arg2 arg3 &more(即写 arg1 arg2 arg3 arg4 & more)不美观,所以他们决定停在 3 args &更多.

I'm assuming that the clojure/core team thought that exposing the arity of partial beyond arg1 arg2 arg3 & more (ie writing arg1 arg2 arg3 arg4 & more) would not be aesthetic, so they decided to stop at 3 args & more.

这篇关于用不同数量的参数重载的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆