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)
一致,后者不起作用。请参阅