假设我有一个使用关键字作为其键的clojure地图:
(def my-car {:color "candy-apple red" :horsepower 450})
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过使用关键字或map作为函数而另一个作为参数来查找与关键字关联的值:
(my-car :color)
; => "candy-apple red"
(:color my-car)
; => "candy-apple red"
Run Code Online (Sandbox Code Playgroud)
我意识到这两种形式在某些情况下都可以派上用场,但是其中一种形式被认为是如上所示的直接使用的惯用语?
ama*_*loy 42
(:color my-car)是相当标准的.这有几个原因,我不会涉及所有这些原因.但这是一个例子.
因为:color是一个常量,而my-car不是,热点可以完全内联动态调度color.invoke(m),它无法做到m.invoke(color)(在某些java伪代码中).
如果my-car碰巧有时候是带有color字段而不是普通地图的记录,那就更好了:clojure编译器可以发出代码来检查"嘿,如果my-car是CarType的实例,那么只返回my-car.color;否则做所有复杂,慢, hashmap查找."
kot*_*rak 24
从图书馆编码标准:
使用关键字优先语法访问对象的属性:
Run Code Online (Sandbox Code Playgroud)(:property object-like-map)使用collection-first语法从集合中提取值(如果集合可能为nil,则使用get).
Run Code Online (Sandbox Code Playgroud)(collection-like-map key) (get collection-like-map key)
我列出了支持和反对这两种形式的论据清单.(编辑:添加第三个选项 - (get map :key)这是我最喜欢的,尽管有点冗长)
1)要求编码标准
http://dev.clojure.org/display/community/Library+Coding+Standards
2)当地图为零时仍然有效
> (:a nil)
nil
> (nil :a)
ERROR: can't call nil
Run Code Online (Sandbox Code Playgroud)
---反驳---如果关键可能是零,其他形式更好
> ({:a "b"} nil)
nil
> (nil {:a "b"})
ERROR: can't call nil
Run Code Online (Sandbox Code Playgroud)
3)更好地用于对象集合的线程化和映射
(-> my-map
:alpha
fn-on-alpha
:beta
fn-on-beta
:gamma
> (def map-collection '({:key "values"} {:key "in"} {:key "collection"}))
> (map :key map-collection)
("values" "in" "collection")
Run Code Online (Sandbox Code Playgroud)
---反驳 - 线程的代码结构与平常不同,因此在需要时可以应用不同的惯用倾向进行地图访问
4)潜在的优化效益?(需要验证)
1)当key为非关键字或nil时,不会抛出错误
> ({:a "b"} nil)
nil
> (nil {:a "b"})
ERROR: can't call nil
> ({"a" "b"} "a")
"b"
> ("a" {"a" "b"})
ERROR: string cannot be cast to IFn
Run Code Online (Sandbox Code Playgroud)
2)在Clojure中与列表访问的一致性
> ([:a :b :c] 1)
:b
> (1 [:a :b :c])
ERROR: long cannot be cast to IFn
Run Code Online (Sandbox Code Playgroud)
3)与其他形式的对象访问相似
java> my_obj .alpha .beta .gamma .delta
clj > ((((my-map :alpha) :beta) :gamma) :delta)
clj > (get-in my-map [:alpha :beta :gamma :delta])
cljs> (aget js-obj "alpha" "beta" "gamma" "delta")
Run Code Online (Sandbox Code Playgroud)
4)从同一个地图访问多个键时的对齐(单独的行)
> (my-func
(my-map :un)
(my-map :deux)
(my-map :trois)
(my-map :quatre)
(my-map :cinq))
> (my-func
(:un my-map)
(:deux my-map)
(:trois my-map)
(:quatre my-map)
(:cinq my-map))
Run Code Online (Sandbox Code Playgroud)
---反驳 - 当从多个地图访问相同的密钥时,对齐更糟糕
> (my-func
(:key map-un)
(:key map-deux)
(:key map-trois)
(:key map-quatre)
(:key map-cinq)
> (my-func
(map-un :key)
(map-deux :key)
(map-trois :key)
(map-quatre :key)
(map-cinq :key)
Run Code Online (Sandbox Code Playgroud)
1)如果arg1是map/vector/nil且arg2是key/index/nil,则不会导致错误
> (get nil :a)
nil
> (get nil nil)
nil
> (get {:a "b"} nil)
nil
> (get {:a "b"} :q)
nil
> (get [:a :b :c] nil)
nil
> (get [:a :b :c] 5)
nil
Run Code Online (Sandbox Code Playgroud)
2)形式与其他Clojure功能的一致性
> (get {:a "b"} :a)
:b
> (contains? {:a "b"} :a)
true
> (nth [:a :b :c] 1)
:b
> (conj [:a :b] :c)
[:a :b :c]
Run Code Online (Sandbox Code Playgroud)
3)地图优先的协调优势
> (my-func
(get my-map :un)
(get my-map :deux)
(get my-map :trois)
(get my-map :quatre)
(get my-map :cinq))
Run Code Online (Sandbox Code Playgroud)
4)Get-in可以通过一次调用用于嵌套访问
> (get-in my-map [:alpha :beta :gamma :delta])
> (aget js-obj "alpha" "beta" "gamma" "delta")
Run Code Online (Sandbox Code Playgroud)
来源:在http://tryclj.com/上测试
| 归档时间: |
|
| 查看次数: |
9907 次 |
| 最近记录: |