请分享您的想法,参与 2024 年 Clojure 状态调查!

欢迎!请访问 关于页面 了解更多该功能的信息。

0
错误

以下错误代码:

(let [[x y] {}] x)

提供了以下堆栈跟踪:

`
异常发生线程 "main" java.lang.UnsupportedOperationException: nth 不支持此类型:PersistentArrayMap (test.clj:0)

    at clojure.lang.Compiler.eval(Compiler.java:4543)
    at clojure.lang.Compiler.load(Compiler.java:4857)
    at clojure.lang.Compiler.loadFile(Compiler.java:4824)
    at clojure.main$load_script__5833.invoke(main.clj:206)
    at clojure.main$script_opt__5864.invoke(main.clj:258)
    at clojure.main$main__5888.doInvoke(main.clj:333)
    at clojure.lang.RestFn.invoke(RestFn.java:413)
    at clojure.lang.Var.invoke(Var.java:346)
    at clojure.lang.AFn.applyToHelper(AFn.java:173)
    at clojure.lang.Var.applyTo(Var.java:463)
    at clojure.main.main(main.java:39)

原因:java.lang.UnsupportedOperationException: nth 不支持此类型:PersistentArrayMap

    at clojure.lang.RT.nth(RT.java:800)
    at clojure.core$nth__3578.invoke(core.clj:873)
    at user$eval__1.invoke(test.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:4532)
    ... 10 more

`

"nth 不支持此类型" 的消息是正确的,但并没有明确错误的原因。在解构时,更好的错误信息将会非常有帮助。

10 个答案

0

评论者:importer

http://www.assembla.com/spaces/clojure/tickets/5 换成

0

评论者:ekoontz

请查看附带的补丁,它会产生(希望更清晰的)错误信息,如下所示(基于原始错误报告中的错误代码):

Clojure 1.4.0-master-SNAPSHOT user=> (let [x 42 y 43] (+ x y)) 85 user=> (let [[x y] {}] x) UnsupportedOperationException left side of binding must be a symbol (found a PersistentVector instead). clojure.lang.Compiler.checkLet (Compiler.java:6545) user=>

此外,此补丁还会检查 (let) 的参数,如下所示:

user=> (let 42) UnsupportedOperationException argument to (let) must be a vector (found a Long instead). clojure.lang.Compiler.checkLet (Compiler.java:6553)

0

评论者:ekoontz

通过将 git diff 与提交 ba930d95fc(master 分支)进行对比生成补丁。

0

评论者:ekoontz

抱歉,这个补丁是错误的:它假设绑定左侧是错误的 -

(let [[x y] {}] x)

因为 {{[x y]}} 是一个向量,但实际上左侧是好的(参考https://clojure.org/special_forms#let:Clojure 在 let 绑定列表中支持抽象结构绑定,通常称为解构)。)

所以需要检查并标记为错误的是右侧({}),而不是 {{[x y]}}。

0

评论者:carinmeier

添加补丁 better-error-for-let-vector-map-binding

这产生了以下结果

(let [[x y] {}] x) 异常:不支持将映射绑定到向量上

尽管如此,还有其他情况没有被此处理 - 例如将向量绑定到集合上

user=> (let [[x y] #{}] x) UnsupportedOperationException nth 不支持此类型:PersistentHashSet

想知道是否可以将映射转换为序列以尝试支持?尽管这可能是另一个问题。

看法如何?

0

评论者:aaron

这看起来过于具体。这是否表明这是一个需要解决的更广泛问题?即使这是绑定产生不良错误消息的唯一情况,上述所有情况都应在补丁中解决。

0

评论者:carinmeier

不幸的是,我意识到这仍然没有涵盖嵌套解构的情况。得出结论,我上面的方法并不适用于解决这个问题。

0

评论者:carinmeier

文件:clj-5-destructure-error.diff

添加了对嵌套解构错误的支持

let [[[x1 y1][x2 y2]] [[1 2] {}]] ;=> UnsupportedOperationException let 无法解构类 clojure.lang.PersistentArrayMap。

0

评论者:hiredman

我对那个错误消息不太满意,let 可以很好地解构 Map。

如果错误消息要更改,我更喜欢得到类似“不支持在 Map 上进行有序解构”的内容。

我实际上喜欢“nth 不受支持”的错误消息,因为它确实是问题所在,nth 是由有序解构使用的,在 Map 上不起作用。

如果你了解解构如何工作以及 nth 的含义,它就会准确地传达问题是什么,而“UnsupportedOperationException let cannot destructure class clojure.lang.PersistentArrayMap”当你了解情况时看起来很误导。

0
参考:[https://clojure.atlassian.net/browse/CLJ-5](https://clojure.atlassian.net/browse/CLJ-5)(由 alex+import 报告)
...