我在4clojure.com执行任务时遇到了问题。 以下是任务说明:
编写一个返回序列中最后一个元素的函数。
我使用以下代码解决了这个问题:
#(first (reverse %))
当我想用一些索引更改first
函数时。
像这样:
#(0 (reverse %))
我收到了错误:
java.lang.ClassCastException:java.lang.Long无法强制转换为 clojure.lang.IFn
我的问题是:
为什么我收到此错误?
我无法得到它,因为例如
([1 2 3 4] 0)
完全有效并返回序列的第一个元素,为什么我不能在函数中使用数组索引?
EDIT1:
即使以下代码也不起作用,我认为APersistentVector
是第一个。
#((reverse %) 0)
EDIT2:
我设法通过将从reverse
函数返回的列表转换为向量来使其工作。谢谢@Josh
(#((vec (reverse %)) 0)[1 2 3])
答案 0 :(得分:8)
如果您查看APersistentVector的代码,您会看到:
public abstract class APersistentVector extends AFn ...
AFn
实现IFn
,它扩展了java的Callable
和Runnable
接口,这意味着可以将clojure持久向量作为函数调用,该参数被用作检索的索引。您可以看到此here:
public Object invoke(Object arg1) {
if(Util.isInteger(arg1))
return nth(((Number) arg1).intValue());
throw new IllegalArgumentException("Key must be integer");
}
地图和集合也是如此;它们都可以作为函数调用:
({: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}
因此,它不能作为函数调用。