为什么参数列表为ArraySeq?

Mic*_*ent 18 arguments clojure

考虑以下功能:

user> (defn first-args [& args]
            (args 0))
#'user/first-args
user> (first-args 1 2 3) ;=> clojure.lang.ArraySeq cannot be cast to clojure.lang.IFn
Run Code Online (Sandbox Code Playgroud)

为什么参数列表是一个clojure.lang.ArraySeq而不是更常见的东西PersistentVector?或者为什么不ArraySeq实施IFn?表现原因?看起来你在做Clojure时必须知道一些事情的基本实现.随意赐教.

PS:这个问题不是"这是不是这个惯用语?" 只是问为什么会这样.

ama*_*loy 23

(defn first-args [& args]
  (first args))

(apply first-args (range)) 
;=> 0
Run Code Online (Sandbox Code Playgroud)

您可以将函数应用于无限参数序列,仅在需要时使用项目.如果&args需要是一个向量(或任何比ISeq更具体的东西),这是不可能的.

至于为什么seqs不可调用:它会鼓励以非常差的方式使用它们.


mik*_*era 5

其他答案已经很好,但只是想提出一种替代方法来实现相同的效果:

(defn first-args [first-arg & others] 
  first-arg)

(first-args 1 2 3)
=> 1
Run Code Online (Sandbox Code Playgroud)

即您可以明确命名函数定义中的第一个参数。