【问题标题】:Clojure: Is using a hash as a function ok? [duplicate]Clojure:使用哈希作为函数可以吗? [复制]
【发布时间】:2015-09-25 05:08:14
【问题描述】:

这两个都有效:

=> (def hash {:a "potato" :b "pants"})
#'hash
=> (hash :a)
"potato"
=> (:a hash)
"potato"

有什么理由我应该更喜欢其中一个而不是另一个?我看到更多的人在做后者(:a hash)...为什么?我喜欢前者(hash :a),因为它类似于(-> hash :a :b :c) 的结构,我更喜欢嘈杂的(get-in hash [:a :b :c])

这些之间有效率差异吗?

【问题讨论】:

标签: clojure hashmap


【解决方案1】:

当您有静态关键字键和动态映射时,请使用(:key hash)。 当你有静态地图和动态键时,使用({:a 1 :b 2} k)。 当映射和键都是动态的时使用(get hash key)。这说明了为什么

> (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,不要为此烦恼。但是键入时间更长,代码可能会因括号而变得混乱。如果您确定cipher 不是nil,那么使用(hm key) 看起来是合理的

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

【讨论】:

    【解决方案2】:

    @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 解释没有热点优化?

    【讨论】:

      猜你喜欢
      • 2011-05-12
      • 2017-04-11
      • 1970-01-01
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多