2012-02-10 2 views
6

지도와 레코드 간의 평등과 관련하여 Clojure의 동작이 혼란 스럽습니다. 이 첫 번째 예에서는 구조적으로 동일한 두 가지 유형이 있습니다.Clojure의 매핑과 평등

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 

이 왜 차이가 있습니다 : 우리는 해시 맵과 구조적으로 동일 기록하지만, = 함수가 false를 돌려주는이 두 번째 예에서는

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 

: 평등 = 함수는 true를 반환? 나는 Clojure 1.3을 사용하고 있으며, 정말 혼란 스럽다. defrecord 대한 참조 문에서

답변

14

: 또한

, defrecord 유형 및 값 계 = 정의되며 는 있는 java.util에 대한 계약에 부합 자바 .hashCode 및 .equals 정의 할 .지도.

따라서 =을 사용할 때 유형이 고려됩니다. 대신 .equals을 사용할 수

user> (.equals titi {:a 1 :b 2}) 
true 
+0

유형 함수가 동일한 유형이 아니므로 PersistentArrayMap 및 PersistentHashMap의 인스턴스가 =와 같은 이유는 무엇입니까? – z1naOK9nu8iY5A

+7

"type-and-value-based ="약속은'defrecord'의 문서화 문자열에 명시되어 있으며 레코드에 적용됩니다. 반면에 일반 맵은 가치 기반의 계획에 참여해야하며, (= (hash-map : foo 1 : bar 2) (sorted-map : foo 1 : bar 2))'와'(= (java.util.HashMap. {: foo 1 : bar 2}) {: foo 1 : bar 2})'는 모두 '참'입니다. –

8
PersistentArrayMap

PersistentHashMap가 개념적으로 동일합니다 - ArrayMap가 성장함에 따라 자동으로 성능상의 이유로는 HashMap로 변환 얻을 것이다. 사용자 수준 코드는 일반적으로이 둘을 구별하지 않아야합니다.

defrecord 데이터 유형은 다른 맵과 동일하지 않습니다. 완전히 다른 인터페이스를 구현할 수있는 별도의 유형이며 다른 형식의 맵으로 자동 대체되지 않아야합니다. 개념적으로 노멀 맵과 같지 않으므로 =은 false를 반환합니다.