Clojure 尝试通过函数调用中的索引获取序列的第一个元素时出错
我在执行来自的任务时遇到了一个问题。 以下是任务的说明: 编写一个函数,返回序列中的最后一个元素 我使用以下代码解决了它:Clojure 尝试通过函数调用中的索引获取序列的第一个元素时出错,clojure,Clojure,我在执行来自的任务时遇到了一个问题。 以下是任务的说明: 编写一个函数,返回序列中的最后一个元素 我使用以下代码解决了它: #(first (reverse %)) 当我想更改第一个函数时,使用了一个索引编号。 像这样: #(0 (reverse %)) 我收到一个错误: java.lang.ClassCastException:无法将java.lang.Long强制转换为 clojure.lang.IFn 我的问题是: 为什么我会收到这个错误? 我不能得到它,因为举例来说 ([1 2 3
#(first (reverse %))
当我想更改第一个
函数时,使用了一个索引编号。
像这样:
#(0 (reverse %))
我收到一个错误:
java.lang.ClassCastException:无法将java.lang.Long强制转换为
clojure.lang.IFn
我的问题是:
为什么我会收到这个错误?
我不能得到它,因为举例来说
([1 2 3 4]0)
完全有效,并返回序列的第一个元素,因此为什么我不能在函数中使用数组的索引
EDIT1:
即使下面的代码也不起作用,我想APersistentVector
是第一个
#((reverse %) 0)
EDIT2:
通过将reverse
函数返回的列表转换为vector,我成功地实现了这一点。谢谢@Josh
(#((vec (reverse %)) 0)[1 2 3])
如果查看的代码,您将看到:
public abstract class APersistentVector extends AFn ...
AFn
实现了IFn
,它扩展了java的Callable
和Runnable
接口,这意味着clojure持久性向量可以作为函数调用,参数用作检索的索引。你可以看到:
地图和集合也是如此;它们都可以作为函数调用:
({:a 1 :b 2} :b) ;; 2
(#{:a :b} :a) ;; :a
([1 2 3 4] 0) ;; 1
但是,Long
(您的数字零)不实现IFn
:
(ancestors (class 42))
=>
#{java.lang.Comparable
java.lang.Number
java.lang.Object
java.io.Serializable}
因此,它不能作为函数调用。但是wait
([1 2 3 4]0)
工作得很好,所以在这个特定的示例中,它如何可能作为函数调用?@FieryCod我不太清楚——任何作为表单第一个元素的clojure持久性向量(如您的示例中的([1 2 3 4]0)
)将始终作为函数调用。“这个特别的例子”是什么意思<代码>第一个是clojure的核心函数,我要说的是一个特殊的例子,我指的是([1 2 3 4]0)
。好的,如果您说任何作为表单第一个元素的持久性向量都将作为函数调用,请告诉我为什么这个#(((反向)0))
会引发错误?如果我理解正确,它应该可以工作,因为PersistentVector
是第一个。您会注意到,当您尝试将该函数应用于序列时给出的错误:ClassCastException clojure.lang.PersistentList无法强制转换为clojure.lang.IFn
<代码>反向不返回向量;它返回一个PersistentList
,而列表不实现IFn
(一个原因是列表不是关联的,即它们不能通过类似于索引的向量进行访问)@fireycod谢谢,您已经很好地解释了这一点。祝你今天愉快:)
(ancestors (class 42))
=>
#{java.lang.Comparable
java.lang.Number
java.lang.Object
java.io.Serializable}