2024 Clojure状态调查!分享您的想法。

欢迎!有关此功能的工作方式,请参阅关于页面以获取更多信息。

0
错误

以下损坏的代码

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

提供以下堆栈跟踪

`
Exception in thread "main" java.lang.UnsupportedOperationException: nth not supported on this type: 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 not supported on this type: 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
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

抱歉,这个补丁是错误的:它假设绑定的左侧是错误的 - 在 {{[x y]}}

(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) 不支持操作异常:对此类型不支持nth:PersistentHashSet

wondering如果我们尝试将映射转换为序列以支持它可能会更好?尽管这可能是另一个问题。

什么看法?

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 可以很好地解构一个映射。

如果错误信息要改变,我更喜欢得到类似于 "序列解构不支持在映射上" 这样的信息。

我实际上喜欢 "nth 不支持" 的错误信息,因为它正好是问题所在,nth,用于序列解构,在映射上不工作。

如果你知道如何解构以及 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 报告)
...