gpt4 book ai didi

用不同数量的参数重载的函数

转载 作者:行者123 更新时间:2023-12-04 22:49:33 24 4
gpt4 key购买 nike

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

例如 (doc partial)返回这个:

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

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

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

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

最佳答案

以下答案是我的猜测:查看 partial 的实现给我们看一看:

(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 & more .但是等等,让我们看看 apply 的实现:
(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 是一个核心函数,当给定不同数量的参数时,它的执行方式不同。这是出于性能原因而应用的优化。这就是暴露部分(和其他此类函数)的不同参数的原因,因为代码的内部执行对于不同的参数是不同的。

我假设 clojure/core 团队认为暴露部分超出 arg1 arg2 arg3 及更多(即编写 arg1 arg2 arg3 arg4 及更多)的数量是不美观的,所以他们决定停止在 3 args 及更多。

关于用不同数量的参数重载的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10769005/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com