clojure - 尝试在函数调用中按索引获取序列的第一个元素时出错

标签 clojure

我在执行 4clojure.com 的任务时遇到问题。 以下是任务的描述:

Write a function which returns the last element in a sequence.

我使用以下代码解决了这个问题:

#(first (reverse %))

当我想用一些索引更改 first 函数时。 像这样:

#(0 (reverse %))

我收到一个错误:

java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn

我的问题是: 为什么我会收到此错误? 我无法得到它,因为例如 ([1 2 3 4] 0) 完全有效并返回序列的第一个元素,那么为什么我不能在函数中使用数组的索引?

编辑1: 即使下面的代码也不起作用,我想 APercientVector 是第一个。

#((reverse %) 0)

编辑2: 我设法通过将从 reverse 函数返回的列表转换为向量来使其工作。谢谢@乔什

(#((vec (reverse %)) 0)[1 2 3])

最佳答案

如果您查看 APersistentVector 的代码,你会看到:

public abstract class APersistentVector extends AFn ...

AFn 实现了 IFn,它扩展了 java 的 CallableRunnable 接口(interface),这意味着 clojure 持久化向量可以作为函数调用,参数用作要检索的索引。你可以看到这个here :

public Object invoke(Object arg1) {
    if(Util.isInteger(arg1))
        return nth(((Number) arg1).intValue());
    throw new IllegalArgumentException("Key must be integer");
}

map 和集合也是如此;它们都可以作为函数调用:

({: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}

因此,它不能作为函数调用。

关于clojure - 尝试在函数调用中按索引获取序列的第一个元素时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45378569/

相关文章:

clojure - 我怎样才能避免使用连续传递风格的堆栈?

lisp - 在哪些情况下更适合使用 Clojure?

macros - 帮我在 Clojure 中写 Cond 宏

clojure - 有没有一些方法可以避免 clojure 中出现这种重复代码?

clojure - 怎么包含?在 Clojure 工作中?

ubuntu - 如何运行 Clojure 文件?

javascript - 如何将此代码和我的想法转换为函数式思维方式 (Clojure)?

clojure - 检测leiningen测试模式

Clojure CLI 清屏

emacs - clojurescript中浏览器Repl、浏览器、http服务器之间的交互