我来自Python,默认情况下不会对地图(即dicts)进行排序.开始学习Clojure,我遇到了这个:
(def point {:x 5 :y 7})
=> #'user/point
point
=> {:x 5, :y 7}
(let [{:keys [x y]} point]
(println "x:" x "y:" y))
x: 5 y: 7
Run Code Online (Sandbox Code Playgroud)
在我看来,为了使这种解构工作,人们将不得不依赖于所订购的地图(当然,还记得订单).真的吗?
Clojure有三种内置的地图类型:数组映射,哈希映射和有序映射.
其中,哈希映射和有序映射是无序的,但实际上是有序数组映射:这在clojure.org官方文档的数据结构部分中有解释.
然而,重要的是要注意,阵列映射主要用于性能原因 - 小地图文字(≤8个条目)被编译为数组映射而不是散列映射,并且assoc新的键到数组映射将返回哈希映射,如果它导致它超过大小阈值.可以通过显式调用来构造更大的数组映射clojure.core/array-map,但是数组映射操作是O(n),因此在存在太多条目时变得相当慢,因此这不是通用有序映射数据结构.
如果你需要一个能够提供良好性能而不管大小的有序地图,你应该使用Alan Malloy的/ Flatland的命令 - 它提供了由内置数据结构支持的持久有序集和映射(一组或一个映射+一个向量)跟踪插入顺序).
Clojure地图不是有序的,尽管有一个这样的东西sorted-map.您正在获得一致的订单,因为您使用密钥来访问值.看看更改密钥名称时会发生什么......
user=> point
{:a 5, :b 7}
user=> (let [{:keys [x y]} point]
#_=> (println "x:" x "y:" y))
x: nil y: nil
nil
user=> (let [{:keys [a b]} point]
#_=> (println "a:" a "b:" b))
a: 5 b: 7
Run Code Online (Sandbox Code Playgroud)
我有一个类似的问题,其答案与您的问题相关.