我在使用core.cache
结合LazyMap
。LazyMap是类似于map的对象(封装map并添加一些逻辑以自动强制与键相关联的延迟值的新数据类型)。
当我开始将lazy map作为FIFO缓存中的值时,我发现所有值都是在map被放入缓存后立即实现的。经过一番挖掘,我发现这可能是由于在clojure.core.cache.wrapped/lookup-or-miss
中的表达式(= ::expired v)
导致的。
实际上,内嵌的=
调用会调用clojure.lang.Util/equiv
(因为LazyMap
实现了IPersistentCollection
),然后,在经过一些调度后,equiv
会被调用以检查lazy map的内容是否等于其他对象(隐含地是另一个map)。这是期望的行为,lazy map实现所有值以使比较成为可能。
然而,当将类似于map的对象与不是map(或集合)的东西进行比较时,如果我们知道它一定会返回false
,那么短路将会受欢迎。但这可能是与Clojure本身以及类似于CLJ-1375的事情更为相关。
如果这不是太大问题,那么可以采取的措施是在clojure.core.cache.wrapped
中将
(= ::expired v)
替换为(identical? ::expired v)
。
它不仅可以修复像我这样的角落案例,还可以让事情稍微快一点(当涉及Clojure关键字时,显式的引用等价性真是太棒了)。
可能还需要更改的表达式(以防万一)包括
(= ::nope ret)
和(= ::nil v)
来自clojure.core.cache
。