Clojure 使用'有什么好处;获取';而是访问地图
就这一问题采取后续行动: 使用clojure进行地图访问有多种方式Clojure 使用'有什么好处;获取';而是访问地图,clojure,Clojure,就这一问题采取后续行动: 使用clojure进行地图访问有多种方式 (def m {:a 1} (get m :a) ;; => 1 (:a m) ;; => 1 (m :a) ;; => 1 我知道我主要使用第二种形式,有时使用第三种形式,很少使用第一种形式。使用每种方法的优点(速度/可组合性)是什么?我不认为存在速度差异,即使是这样,这也是一个实现细节 就我个人而言,我更喜欢第二个选项(:am),因为它有时会让代码看起来更简单。例如,我经常需要遍历一系列贴图: (def
(def m {:a 1}
(get m :a) ;; => 1
(:a m) ;; => 1
(m :a) ;; => 1
我知道我主要使用第二种形式,有时使用第三种形式,很少使用第一种形式。使用每种方法的优点(速度/可组合性)是什么?我不认为存在速度差异,即使是这样,这也是一个实现细节 就我个人而言,我更喜欢第二个选项(:am),因为它有时会让代码看起来更简单。例如,我经常需要遍历一系列贴图:
(def foo '({:a 1} {:a 2} {:a 3}))
如果我想过滤:a的所有值,我现在可以使用:
(map :a foo)
而不是
(map #(get % :a) foo)
或
当然,这是个人喜好的问题。你可以将
get
传递到partial
等,以建立HOF,从而干扰你的数据,尽管它并不经常出现
user=> (def data {"a" 1 :b 2})
#'user/data
user=> (map (partial get data) (keys data))
(1 2)
当数据中有字符串作为键时,我经常使用第三种形式
映射实现IFn,用于带有
可选的第二个参数(默认值),即映射是
他们的钥匙。nil键和值都可以
有时,在Clojure的兜帽下看一看是值得的。如果在地图中查找invoke
的外观,您会看到:
它显然调用了map的valAt
方法
如果您查看get
函数在使用map调用时的功能,这是对clojure.lang.RT.get
的调用,这实际上归结为对map的valAt
的相同调用(map实现ILookUp,因为它们是:
对于使用键和未找到值调用的映射也是如此。那么,优势是什么?由于这两种方法归结起来几乎相同,所以在性能方面我什么也不说。这只是语法上的方便
get
在map可以是nil或not-a-map,并且键可以是不可调用的东西(即不是关键字)时非常有用
要添加到列表中,get在使用线程宏
->
时也很有用,您需要通过非关键字的键进行访问
(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
(设[m{“a”:a}]
(->m
(得到“a”))
使用关键字优先法的一个优点是,在地图为零的情况下,它是以宽容的行为访问值的最简洁的方法。请参阅您链接的问题中的答案。get唯一想到的另一件事是3-arity版本(找不到get映射键),在该版本中,您可以指定默认值。@a.Webb您可以为所有三种用途指定默认值:(:k m default)
和(m:k default)
,只要m当然不是零。@amalloy啊,酷,谢谢你指出这一点!这并不能真正解决问题。您可以同样轻松地(映射数据(键数据))
获得与(VAL数据)
等价的数据。要点是,get可以与函数转换函数组合,以在数据映射可用之前生成数据旋转函数。这个例子说明了这一点,虽然在实践中它与其他特定于问题的约束结合在一起。
(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