请在 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 时才调用equiv。

1 答案

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

这可能会要求在 lazy-map 中进行修复,但这种情况发生的原因是,延迟映射被用作缓存中某个键的关联值,当比较整个映射到一个特殊值 ::expired(一个关键字)时使用 = 函数。clojure.core/=将抽象分散到 clojure.lang.Util/equiv,它调用了 clojure.lang.Util/pcequiv。因此,缓存中保留的整个映射作为一个值立即实现(计算延迟的当前值),以便获取其实际内容 - 即使它是与一个关键字比较的!

在延迟映射实现中(通过检查比较的两个对象是否实际上是集合),在核心缓存中(通过使用 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 集合进行比较,因此我认为你的情况并不涵盖其中,除了纯实现机制外。
...