考虑以下函数:
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
为什么参数列表是一个clojure.lang.ArraySeq
,而不是像PersistentVector
这样更常见的东西?或者为什么ArraySeq
不实现IFn
?性能原因?在做Clojure时,似乎你必须了解一些底层的实现。请随时给我启迪。
PS:这个问题不是关于“这是不是惯用的?”我只是在问为什么会是这样。
发布于 2011-11-21 06:53:33
(defn first-args [& args]
(first args))
(apply first-args (range))
;=> 0
您可以将函数应用于无限参数序列,仅在需要时使用项。如果要求&
args是一个向量(或任何比ISeq更具体的东西),这是不可能的。
至于为什么seqs是不可调用的:它会鼓励以一种性能非常差的方式使用它们。
发布于 2011-11-21 13:53:30
其他答案已经很好了,但只是想提出一种替代方案来实现同样的效果:
(defn first-args [first-arg & others]
first-arg)
(first-args 1 2 3)
=> 1
也就是说,您可以显式地命名函数定义中的第一个参数。
发布于 2011-11-21 06:31:19
在第2行中,您将args
作为一个函数进行调用。您想要的实际上是:
(defn first-args [& args]
(first args))
向量实际上比向量更“常见”,因为向量继承了ISeq。这就是为什么你不能在这里做列表,这似乎是你想要调用的,因为它只适用于地图和向量,而不适用于任何列表(如ISeq )。
https://stackoverflow.com/questions/8205209
复制相似问题