请在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 的当前值),以便获得其实际内容——即使它被与一个关键字比较!

在惰性映射实现中,可以通过检查要比较的两个对象是否实际上是集合来解决/解决方法,在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集合,所以我认为你的情况不应该包含在内,除了纯粹的实施机制。
...