在《2024 年 Clojure 状况调查!》中分享你的想法。

欢迎!请访问关于页面以获取有关该功能的更多信息。

+1
Collections

Util.pcequiv() 方法

`
static public boolean pcequiv(Object k1, Object k2){

if(k1 instanceof IPersistentCollection)
	return ((IPersistentCollection)k1).equiv(k2);
return ((IPersistentCollection)k2).equiv(k1);

}
`

试图为混合 Clojure/Java 集合比较的情况获取等价语义(跨类数字相等)。然而,这不是一个可持续的方向,我们希望停止这样做。

附加补丁移除了此部分,并将调用代码改为仅在两个集合都是 IPersistentCollection 时调用等价。

1 答案

+1
参考:https://clojure.atlassian.net/browse/CLJ-1375 (报告人:alexmiller)
我今天遇到了涉及 core.cache 和 raxod502/lazy-map 的影响边缘情况。lazy-map 实现定义了一个实现 clojure.lang.IPersistentCollection 的类型及其等价方法(通过在当前对象强制实现为常规映射时调用 .equiv)。

这可能需要在 lazy-map 中进行修复,但发生这种情况的原因是 lazy-map 作为缓存中某个键的值,而 clojure.core.cache.wrapped/lookup-or-miss 在比较整个映射与特殊值 ::expired(一个关键字)时使用 = 函数。clojure.core/= 在 clojure.lang.Util/equiv 中安排  到 clojure.lang.Util/pcequiv。因此,缓存中保存的整个映射作为其中一个值立即实现(当前 Delays 的值被计算),以便获取其实际内容 - 即使它被与关键字进行比较!

在懒映射实现中(通过检查比较的两个对象是否实际是集合),在 core.cache(通过使用 identical? 而不是 = 来检查循环中的值是否是特定的关键字)或通过应用此补丁来解决问题。
by
我不确定这对我来说有没有意义——被比较的值中是否有一个是 Java 非Clojure 集合?
by
1. LazyMap 对象(实现 IPersistentCollection)使用 clojure.core/= 与关键字进行比较

2. clojure.core/= 调用 clojure.lang.Util/equiv

3. clojure.lang.Util/equiv 调用 clojure.lang.Util/pcequiv

4. pcequiv 调用 LazyMap 的 IPersistentCollection 实现的 equiv,导致所有延迟的值都被实现(这在比较两个映射时是必要的),即使另一个对象是关键字(在特定条件下用来传达信息,在这种情况下是 :clojure.core.cache.wrapped/expired)。
by
此处讨论的工单是关于比较 Java 集合和 Clojure 集合的,因此我认为您的案例不会由该机制覆盖,而仅由纯实现机制覆盖。
...