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 的边缘情况。懒惰映射实现定义了一个实现 clojure.lang.IPersistentCollection 类型的类型,以及它的等价方法(通过在当前对象上强制调用 .equiv,使其成为常规映射)。

这可能在lazy-map中仍然需要修复,但发生的原因是,延迟图被用作缓存中某些键的关联值,并且clojure.core.cache.wrapped/lookup-or-miss在将整个映射与特殊值::expired(一个关键字)进行比较时使用了=函数。clojure.core/=将分发到clojure.lang.Util/equiv,该函数调用clojure.lang.Util/pcequiv。因此,缓存中持有的整个映射作为其中一个值立即被实例化(计算delays的当前值),以便获取其实际内容 - 即使它与一个关键字进行比较!

在lazy map实现中可以采取权宜之计/解决方案(通过检查两个比较的对象是否真的是集合),在core.cache中(通过使用identical?代替=来检查循环中的值是否是特定的关键字)或通过应用此补丁。
by
我不确定这对我来说是否有意义 - 被比较的值之一是一个Java非Clojure集合吗?
by
1. 与关键字使用clojure.core/=比较实现了IPersistentCollection的LazyMap对象。

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集合,所以我认为你的情况不是由纯实现机制,而是由该票证涵盖的。
...