首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么参数列表为ArraySeq?

为什么参数列表为ArraySeq?
EN

Stack Overflow用户
提问于 2011-11-21 06:19:35
回答 3查看 3.9K关注 0票数 19

考虑以下函数:

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:这个问题不是关于“这是不是惯用的?”我只是在问为什么会是这样。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-11-21 06:53:33

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

(apply first-args (range)) 
;=> 0

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

至于为什么seqs是不可调用的:它会鼓励以一种性能非常差的方式使用它们。

票数 26
EN

Stack Overflow用户

发布于 2011-11-21 13:53:30

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

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

(first-args 1 2 3)
=> 1

也就是说,您可以显式地命名函数定义中的第一个参数。

票数 5
EN

Stack Overflow用户

发布于 2011-11-21 06:31:19

在第2行中,您将args作为一个函数进行调用。您想要的实际上是:

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

向量实际上比向量更“常见”,因为向量继承了ISeq。这就是为什么你不能在这里做列表,这似乎是你想要调用的,因为它只适用于地图和向量,而不适用于任何列表(如ISeq )。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8205209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档