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

欢迎!关于如何使用本站,请查看关于页面以获得更多信息。

0
ClojureScript
{{js->clj}} 表示


  (cond

    [...]
                
    (coll? x)
    (into (empty x) (map thisfn x))


问题是,{{(coll? x)}} 检查 ICollection,而 {{(empty x)}} 需要 IEmptyableCollection。当 x 通过第一个测试但未通过第二个测试时,{{js->clj}} 会抛出 "错误:没有为类型 : [object Object] 定义协议方法 IEmptyableCollection.-empty"。  

由于 {{js->clj}} 会递归处理那些可能什么都有但就是没有厨房用具的 JavaScript 对象,它不可避免的是一种尽力而为而不是高原则的方法。简而言之,这里可不是吹毛求疵的地方。如果集合不可为空,我期望 {{js->clj}} 尽力保持顺序但不是类型:使用向量!

5 个答案

0

评论作出者:rohitaggarwal

(链接:~pbwolf)你能给出一个具体的失败案例吗?

0

评论作出者:jszakmeister

在这里很难给出具体的案例——它似乎仅在高级编译中真正显现。我曾有一个从服务器返回类似以下内容的例程:{"Br": 0, "B": 100, "P": 1000} 作为 JSON。js->clj会在生成过程中触发描述中提到的 "没有协议方法" 错误。我发现,如果移动这个片段

`
(identical? (type x) js/Object)
(into {} (for [k (js-keys x)]

       [(keyfn k) (thisfn (unchecked-get x k))]))

`

这段代码前面的内容

(coll? x)(into(empty x)(map thisfn x))

错误消失了,但我不能确定这么做是否正确。我怀疑键又在以某种方式与已知的东西冲突,有些东西在事实上并不被视为集合时却被当作集合处理。然后,当调用(empty x)时,因为对象没有实现所需的协议,所以我们失败了。

我认为这种情况在 CLJS-1658 和 7e15b1f2b894d93ef94ff86d75226f1fd3919580 中已经被修复了,但也许我们还遇到了其他的错误,导致再次出现错误。

0

评论者:thheller

这可能无法修复,而不会破坏其他人概念中 js->clj 的语义。至少我想不出简单的方法。

下面是事件的简要重现

  • coll? 检查 ICollection,这是一个快速路径协议
  • 快速路径协议执行一些位检查,而不是之前固定的哨兵检查
  • 位检查是在一个名为 {{cljs$lang$protocol_mask$partition0$}} 的属性上执行的,这个属性被 Closure 简化为一些未知的内容。考虑到你的示例中 Object 的“简短”键,在 Closure 以 a、b、c、... 开始的情况下,这很有可能导致冲突。

这可以在 Node REPL 中重现

`
[6:1]~cljs.user=> (def obj #js {"cljs$lang$protocol_mask$partition0$" 8})

'cljs.user/obj

[6:1]~cljs.user=> (coll? obj)
true
[6:1]~cljs.user=> (empty obj)
评估错误 Error: No protocol method IEmptyableCollection.-empty defined for type object: [object Object]
`

一个简单的修复方法是仅仅忘记 js->clj 并使用仅支持 JSON 值而不使用协议的东西。

我这里有一个你可以使用的
https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/json.cljs#L4-L37

也许我们应该向核心添加一个 json->clj 并适当记录 js->clj 的错误行为?

0

评论作出者:jszakmeister

{quote}
也许我们应该向核心添加一个 json->clj 并适当记录 js->clj 的错误行为?
{quote}

我认为这是明智的。很久以前,我已在项目中实现了自己的 json->clj 来解决这个问题,但我认为在核心中添加这将对这里非常有帮助。

顺便说一句,重现方法做得很好。遗憾的是,高级编译将其缩短为可能冲突的内容。

0
参考资料: https://clojure.atlassian.net/browse/CLJS-2062 (由 alex+import 报告)
...