有什么优势可以使用'get'代替访问地图

zca*_*ate 6 clojure

从这个问题开始:通过关键字查找惯用语clojure map

使用clojure进行地图访问可以通过多种方式完成.

(def m {:a 1}

(get m :a) ;; => 1
(:a m) ;; => 1
(m :a) ;; => 1
Run Code Online (Sandbox Code Playgroud)

我知道我主要使用第二种形式,有时是第三种形式,很少是第一种形式.使用每个的优点(速度/可组合性)是什么?

Chr*_*ins 12

get 当地图可能是nil或not-a-map时,该键很有用,并且键可能是不可调用的(即不是关键字)

(def m nil)
(def k "some-key")

(m k)  =>  NullPointerException
(k m)  =>  ClassCastException java.lang.String cannot be cast to clojure.lang.IFn

(get m k)  =>  nil
(get m :foo :default)  =>  :default
Run Code Online (Sandbox Code Playgroud)


Mic*_*ent 3

clojure网页我们看到

映射实现 IFn,用于一个参数(键)和可选的第二个参数(默认值)的 invoke(),即映射是其键的函数。nil 键和值都可以。

有时深入了解 Clojure 的底层是值得的。如果您查看invoke地图中的内容,您会看到以下内容:

https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APercientMap.java#L196

它显然调用了valAtmap的方法。

如果您查看get使用映射调用该函数时的作用,就会发现这是对 的调用clojure.lang.RT.get,这实际上归结为valAt对映射的相同调用(映射实现 ILookUp 因为它们是Associatives):

https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L634

对于使用键和未找到值调用的映射也是如此。那么,有什么好处呢?由于这两种方式归结起来几乎是相同的,所以在性能方面我什么也不说。这只是语法上的便利。