学习clojure的apply函数。
函数形式
(apply f args)
(apply f x args)
(apply f x y args)
(apply f x y z args)
(apply f a b c d & args)
文档
Applies fn f to the argument list formed by prepending intervening arguments to args.
对clojure的参数命名不太熟悉,对上面的英文有点困惑,看了源码就清楚了。
先将arguments插入到args的前面(也就是将x y z a b c d这些参数插入到args这个列表的前面,比如参数部分的形式是这样,x y [1 2 3],那么先将参数整理成[x y 1 2 3]这种形式),再将函数f应用到这个整理后的参数列表上。
对clojure的参数命名不太熟悉,对上面的英文有点困惑,看了源码就清楚了。
先将arguments插入到args的前面(也就是将x y z a b c d这些参数插入到args这个列表的前面,比如参数部分的形式是这样,x y [1 2 3],那么先将参数整理成[x y 1 2 3]这种形式),再将函数f应用到这个整理后的参数列表上。
源码
(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)))))))))
注:clojure中的每个函数都实现了IFn接口,而AFn是实现了IFn接口的抽象类,位于clojure.lang包下面。在AFn抽象类中,包含了apply方法。
apply先将变长参数部分(arguments)插入到列表式参数(args)的前端,然后再调用f的applyTo方法。
applyTo的方法代码如下,利用了Helper方法,Helper主要是完成从列表到独立参数的转换。
public Object applyTo(ISeq arglist) {
return applyToHelper(this, Util.ret1(arglist,arglist = null));
}