Map Clojure中的映射和记录平等
我发现Clojure的行为混淆了映射和记录之间的平等性。在第一个例子中,我们有两种不同的类型,它们在结构上是相等的。equality=函数返回true:Map Clojure中的映射和记录平等,map,clojure,record,equality,Map,Clojure,Record,Equality,我发现Clojure的行为混淆了映射和记录之间的平等性。在第一个例子中,我们有两种不同的类型,它们在结构上是相等的。equality=函数返回true: user> (defn make-one-map [] {:a "a" :b "b"}) #'user/make-one-map user> (def m1 (make-one-map)) #'user/m1 user> m1 {:a "a", :b "b"} user> (def m2
user> (defn make-one-map
[]
{:a "a" :b "b"})
#'user/make-one-map
user> (def m1 (make-one-map))
#'user/m1
user> m1
{:a "a", :b "b"}
user> (def m2 {:a "a" :b "b"})
#'user/m2
user> m2
{:a "a", :b "b"}
user> (= m1 m2)
true
user> (type m1)
clojure.lang.PersistentArrayMap
user> (type m2)
clojure.lang.PersistentHashMap
在第二个示例中,我们有一个hashmap和一个记录,它们在结构上是等价的,但是=函数返回false:
user> (defrecord Titi [a b])
user.Titi
user> (def titi (Titi. 1 2))
#'user/titi
user> titi
#user.Titi{:a 1, :b 2}
user> (= titi {:a 1 :b 2})
false
为什么会有差异?我正在使用Clojure 1.3,我发现它们非常混乱。来自
defrecord
的docstring:
此外,defrecord将定义基于类型和值的=,并将
定义的Java.hashCode和.equals与
java.util.Map
因此,在使用=
时,会考虑类型。您可以使用.equals
:
user> (.equals titi {:a 1 :b 2})
true
persistentarymap
和PersistentHashMap
在概念上是相同的-随着ArrayMap的增长,出于性能原因,它将自动转换为HashMap。用户级代码通常不应试图区分两者
另一方面,
defrecord
数据类型与其他映射之一不同。它是一个单独的类型,可以实现完全不同的接口,不应该被其他形式的映射自动替换。它在概念上并不等于普通映射,因此=
返回false。为什么PersistentArrayMap和PersistentHashMap的实例与=then相等,因为type函数指示它们不是同一类型?在defrecord
的docstring中声明了“type and value-based=”promise,并应用于记录。另一方面,常规映射应该参与一个基于值的=方案,而且它们确实参与了,(=(hash-map:foo 1:bar 2)(排序映射:foo 1:bar 2))
和(=(java.util.HashMap.{:foo 1:bar 2}){:foo 1:bar 2})
都是true
。