ILookup 有什么用,为什么它不扩展 IFn?

What is ILookup for and why doesn't it extend IFn?

地图似乎两者兼而有之,我们可以两者兼顾

({:a 1} :a)

(因为它是一个 IFn)和

(:a {:a 1})

因为它是一个 ILookup。此外,RT/getFrom 允许按索引查找字符串和数组,Java 以类似的方式按键查找映射和按成员查找 IPersistentSets

除了可以在其上使用关键字之外,ILookup 还为您提供了什么?为什么这比 IFn 更好?

特别是,datomic.EntityMap 似乎是一个 ILookup 而不是 IFn。

clojure.lang.ILookup 用于可以查找键(任意类型,不一定是关键字)的事物。 clojure.lang.IFn 用于可以作为函数调用的事物。仅根据这些使命陈述,尚不清楚它们之间是否存在任何内在的 link。

此外,ILookupIFn 并不总是以相同的方式实现 valAtinvoke

(.valAt [0 1 2] 123)
;= nil

([0 1 2] 123)
;; throws IndexOutOfBoundsException

上述行为的原因是 invoke 在矢量上的工作方式类似于二进制 nth,而 valAt 的目的是实现 get 的语义。

(关于 invoke 对向量 应该 做什么的主题可能存在分歧,但这是一个单独的讨论。)

None 这意味着 ILookupIFn "better" – 它只是一个单独的接口,具有单独的目的。在他们之间引入 extends 关系是有原因的,我不确定此时这样做会有什么好处。