Clojure:使用散列作为函数可以吗?

Clojure:使用散列作为函数可以吗?,clojure,hashmap,Clojure,Hashmap,这两种方法都有效: => (def hash {:a "potato" :b "pants"}) #'hash => (hash :a) "potato" => (:a hash) "potato" 有什么理由让我喜欢其中一个而不是另一个吗?我看到越来越多的人在做后一种(:散列)。。。为什么?我喜欢前一个(hash:a),因为它类似于(>hash:a:b:c),我更喜欢噪音更大的(get in hash[:a:b:c]) 这两者之间有效率上的差异吗?由@leeor给出的链接非

这两种方法都有效:

=> (def hash {:a "potato" :b "pants"})
#'hash
=> (hash :a)
"potato"
=> (:a hash)
"potato"
有什么理由让我喜欢其中一个而不是另一个吗?我看到越来越多的人在做后一种
(:散列)
。。。为什么?我喜欢前一个
(hash:a)
,因为它类似于
(>hash:a:b:c)
,我更喜欢噪音更大的
(get in hash[:a:b:c])


这两者之间有效率上的差异吗?

由@leeor给出的链接非常全面。我将在这里再添加一点实验:

user> (time (let [m {:a :b}] (dotimes [i 900000000] (m :a))))
"Elapsed time: 4609.565862 msecs"
=> nil
user> (time (let [m {:a :b}] (dotimes [i 900000000] (get m :a))))
"Elapsed time: 9556.065868 msecs"
=> nil
user> (time (let [m {:a :b}] (dotimes [i 900000000] (:a m))))
"Elapsed time: 11220.804791 msecs"
=> nil
这个结果与@amalloy关于热点优化的观点相矛盾。可能是因为REPL解释没有进行热点优化?

当您有静态关键字键和动态映射时,请使用
(:key hash)
。 当您有静态映射和动态键时,请使用
({:a1:b2}k)
。 当映射和键都是动态的时,使用
(获取哈希键)
。这说明了原因

> (def hm nil)
> (def knil nil)
> (def kother 1)

> (hm :key)
NullPointerException ...
> (:key hm)
nil

> (kother {:a 1})
ClassCastException
> (knil {:a 1})
NullPointerException
> ({:a 1} kother)
nil

> (get hm knil)
nil
> (get hm kother)
nil
或者你可以在任何地方使用
get
,而不必为此烦恼。但它的输入时间更长,并且代码可能会因为括号而变得混乱。如果您确定
密码
不是

> (def message "hello")
> (let [cipher {\h \1 \e \f \l \# \o \p}]  
    (apply str (map cipher message)))
"1f##p"

Hash first也与
([:a:b:c]2)
一致,后者不起作用。请参阅