Clojure 为什么使用关键字或符号作为函数从地图中查找值有效?

Clojure 为什么使用关键字或符号作为函数从地图中查找值有效?,clojure,Clojure,引用Clojure的Joy,第4.3.1节-- 因为关键字是自评估的,并提供快速的相等性检查,所以它们几乎总是在映射键的上下文中使用。将关键字用作映射键的一个同样重要的原因是,它们可以用作函数,将映射作为参数,以执行值查找: 我不清楚这里发生了什么。不知何故,(:僵尸种群)必须转换成(获取种群:僵尸),对吗?这到底是怎么回事?关键字的计算结果为自身,而不是函数。读者是否注意列表中第一件事是关键字的情况,并将关键字添加到列表末尾?引文来源: 关键字使用可选的第二个参数(默认值)为一个参数(映射)的

引用Clojure的Joy,第4.3.1节--

因为关键字是自评估的,并提供快速的相等性检查,所以它们几乎总是在映射键的上下文中使用。将关键字用作映射键的一个同样重要的原因是,它们可以用作函数,将映射作为参数,以执行值查找:

我不清楚这里发生了什么。不知何故,
(:僵尸种群)
必须转换成
(获取种群:僵尸)
,对吗?这到底是怎么回事?关键字的计算结果为自身,而不是函数。读者是否注意列表中第一件事是关键字的情况,并将关键字添加到列表末尾?

引文来源:

关键字使用可选的第二个参数(默认值)为一个参数(映射)的invoke()实现IFn。例如(:mykey my hash map:none)的意思与(get my hash map:mykey:none)相同。看得到


Clojure可以将关键字作为函数调用,因为它实现了与函数相同的接口。符号也是如此…

关键字实现IFn

它的invoke方法处理对get的调用。

关键字在各个方面都是函数。如果您尝试
(让[m{:humans 100},k:humans](km))
,您将看到,没有读者魔法。我希望您同意,读者不可能将此转换为get(编译器可以,但您可以假装我已使
k
的值取决于编译器无法预测的if表达式,例如用户输入)

因为Clojure的核心数据类型是接口,Java对象可以实现许多接口,所以一段数据可以有多种类型。这是一个关键词吗?对它是一个函数吗?还有:

user> (keyword? :k)
true
user> (ifn? :k)
true
user> (.invoke :k {:k 1})
1

有趣的是,第一个参数不一定是映射:(:foo:bar:baz)产生:baz@KingCode如果它不是
ILookup
、java
Map
IPersistentSet
,则
RT
中的
getFrom
只返回
null
,在这种情况下,
Keyword
中的
invoke
方法只返回
notFound
值,或者示例中的
:baz
user> (keyword? :k)
true
user> (ifn? :k)
true
user> (.invoke :k {:k 1})
1