【问题标题】:Error while trying to get first element of sequence by index in a function call尝试在函数调用中按索引获取序列的第一个元素时出错
【发布时间】:2017-07-29 02:15:52
【问题描述】:

我在执行来自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])

【问题讨论】:

    标签: clojure


    【解决方案1】:

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

    public abstract class APersistentVector extends AFn ...
    

    AFn 实现 IFn,它扩展了 java 的 CallableRunnable 接口,这意味着可以将 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}
    

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

    【讨论】:

    • 但是等待([1 2 3 4] 0) 工作正常,那么在这个特定示例中它怎么可能作为函数调用呢?
    • @FieryCod 不确定我是否理解——任何作为表单第一个元素的 clojure 持久向量(如您的示例中的 ([1 2 3 4] 0) )将始终作为函数调用。你是什​​么意思,“这个特殊的例子”? first 是一个 clojure 核心函数,只是要明确一点。
    • 通过特定的例子我的意思是([1 2 3 4] 0)。好的,如果您说任何作为表单第一个元素的持久向量都将作为函数调用,请告诉我为什么这个#(((reverse %) 0)) 会引发错误?如果我理解正确,它应该可以工作,因为PersistentVector 是第一位的。
    • 您会注意到当您尝试将该函数应用于序列时出现的错误:ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFnreverse 不返回向量;它返回一个PersistentList,并且列表没有实现IFn(一个原因是列表不是关联的,即它们不能通过像向量这样的索引来访问)@FieryCod
    • 谢谢你,你已经完美地解释了。祝你有美好的一天:)
    猜你喜欢
    • 2022-08-22
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多