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