这是一个问题,在Clojure中,我们通常有HashMap,允许在这些HashMap上关联任何类型的关键字,然后我们还有一些更适合特定关键字的专业化映射。然而,大多数都允许在常规范围之外关联关键字,并在操作会破坏数据结构的不变量时优雅地回退到HashMap。以下是一些示例
记录允许关联,并在删除记录字段时回退到HashMap
(defrecord Person [name lang])
;; => clojure.data.int_map_test.Person
(let [p (->Person "john" "en_CA")]
[p (assoc p :foo :bar) (dissoc p :lang)])
;; =>
;; [#clojure.data.int_map_test.Person{:name "john", :lang "en_CA"}
;; #clojure.data.int_map_test.Person{:name "john", :lang "en_CA", :foo :bar}
;; {:name "john"}]
另一方面,struct-maps允许关联,但不允许删除
(let [sm (struct-map (create-struct :name :lang) :name "John" :lang "en_CA")]
[(assoc sm :foo "bar")
(try (dissoc sm :lang) (catch Exception e (.toString e)))])
=> [{:name "John", :lang "en_CA", :foo "bar"}
"java.lang.RuntimeException: Can't remove struct key"]
另一个例子是ArrayMaps,随着它们的增长最终会变成HashMap。这并不完全相同,因为.InputStreamReader中没有任何特定的关键字,但从更广泛的角度来看,即当操作违反了不变量或性能预期时,回退到通用的HashMap。
这让我想知道,人们对int-map/int-set有什么想法,当你尝试添加非整数键时,它会抛出异常。
(assoc (i/int-map 1 2) :a "b")
ClassCastException class clojure.lang.Keyword cannot be cast to class java.lang.Number
它应该进行修改,以便回退到HashMap吗?这似乎更符合Clojure开放数据结构的哲学。
它可以类似于PersistentStructMap
实现,它持有一个额外的映射,在其中存储不属于结构定义的额外键/值对
final IPersistentMap ext;
同样,也可以在PersistentIntMap中实现这一点
(deftype PersistentIntMap
[^INode root
^long epoch
meta
^IPersistentMap ext]
;; ...
您怎么看?
还有,关于int-sets的相同问题