在clojure中,您可以同时使用映射和键作为查找函数({:a 1 :b 2} :a)
和(:a {:a 1 :b 2})
都是可行的查找函数。
那么为什么可以使用map作为查找复合键的函数,而不能使用其他方法呢?
这意味着({[:compound :mebaby] 1} [:compound :mebaby]})
将返回1
,但([:compound :mebaby] {[:compound :mebaby] 1})
将抛出错误。
关键字实现IFn
作为它们的特性之一,使它们方便地用作键。它们实现的fn是在关联结构参数中查找它们自己。对于像vector这样的集合来说,情况并非如此,因为它们实现了IFn
来在参数key处进行查找。
因此,({[:compound :mebaby] 1} [:compound :mebaby]})
询问映射键[:compound :mebaby]
的值是多少,这个键存在。但是([:compound :mebaby] {[:compound :mebaby] 1})
询问向量在索引{[:compound :mebaby] 1}
处的值是多少。这不是一个整数,所以它不能是vector中的索引/键,并抛出错误。
原因是:您的复合键不再是关键字。它现在是一个向量,尽管仍然是IFn
,但它只接受整数(例如i
)作为参数,返回向量的i
元素。
我怀疑你真正想要的是从嵌套映射中提取值,就像从{:a {:b "c"}}
中提取字符串"c"一样。如果是,这两种形式是等价的:
(get-in {:a {:b "c"}} [:a :b])
;=> "c"
((comp :b :a) {:a {:b "c"}})
;=> "c"
您可以使用键作为查找函数的假设是不正确的。可以使用关键字作为查找函数。在您的示例中,:a
是一个关键字。所以它可以用作查找函数。但[:compound :mebaby]
不是关键字,而是矢量。向量不能用作查找函数