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 约束的左侧必须是一个符号(找到 PersistentVector)。 clojure.lang.Compiler.checkLet (Compiler.java:6545) user=>

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

user=> (let 42) UnsupportedOperationException (let) 的参数必须是一个向量(找到 Long)。 clojure.lang.Compiler.checkLet (Compiler.java:6553)

0
by

评论者:ekoontz

此补丁是通过在提交 ba930d95fc(master 分支)上做 git diff 生成的。

0
by

评论者:ekoontz

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

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

因为 {{[x y]}} 是一个向量,而实际上左侧并无错误(详见 https://clojure.org/special_forms#let: "Clojure 支持抽象结构绑定,通常称为解构,在 let 绑定列表中"。)

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

0
by

评论者:carinmeier

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

这会产生以下结果

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

尽管如此,还有一些其他情况没有被这个处理,比如将向量绑定到集合

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

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

有什么想法吗?

0
by

评论者:aaron

这似乎过于具体。这个问题是更大问题的表征,应该解决这个问题吗?即使这只是绑定产生不良错误信息的唯一案例,所有上述情况都应在补丁中得到解决。

0
by

评论者:carinmeier

遗憾的是,我意识到这仍然不能涵盖嵌套解构的情况。得出结论,我上述的方法对于这种情况是不适用的。

0

评论者:carinmeier

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

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

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

0

评论人:hiredman

我对该错误消息不太满意,let 仍能很好地解构地图。

如果错误消息要改变,我更喜欢得到类似 "在地图上不支持顺序解构" 的内容。

我实际上喜欢 "nth 不受支持" 的错误消息,因为它正是问题所在,nth,用于顺序解构,不适用于地图。

如果你了解解构方式和 nth 含义,它会精确地传达问题所在,而"let无法解构class clojure.lang.PersistentArrayMap"的UnsupportedOperationException似乎有些误导

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