지도 리터럴의 평가 순서에 구현 세부 사항을 고려하고지도 리터럴에 부작용 (예 : 원자 상태 설정)이있는 상수가 아닌 표현식을 사용하여 문제를 묻는 방법을 생각해 보겠습니다.
잘 정의 된 평가 의미에 대해서는 함수 호출을 사용하십시오. 여기서 인수는 왼쪽에서 오른쪽으로 평가되는 것이 보장됩니다.
(let [i (atom 0)]
(hash-map :a (swap! i inc) :b (swap! i inc) :c (swap! i inc)))
;=> {:a 1, :c 3, :b 2}
해시 맵을 사용했기 때문에 키 순서가 맞지 않지만 값은 작성된 순서대로 키에 해당합니다.
이
독자가 순서 배열지도로 평가되지 않은지도 리터럴을 취급 :
구현 세부 사항
(버전 1.5)지도 리터럴의 구현 세부 사항은 몇 가지에 따라 달라집니다 작은지도 (8 쌍 이하) 또는 큰지도에 대한 정렬되지 않은 해시지도.
컴파일러 평가 기는 키와 값이 상수 식인 경우 정렬되지 않은 해시 맵으로 판독기가 제공하는 맵 식을 구문 분석하지만이를 배열 맵으로 평가합니다. 그렇지 않으면 컴파일러 평가 기는 크기에 따라 독자가 제공하는 키 순서로 평가합니다.
작은 예는이 것 좀 명확하게 (아마도) :
user=> {:a 1, :b 2, :c 3}
{:a 1, :c 3, :b 2}
user=> (type *1)
clojure.lang.PersistentArrayMap
user=> (def m1 {:a 1, :b 2, :c 3})
#'user/m1
user=> m1
{:a 1, :c 3, :b 2}
user=> (type m1)
clojure.lang.PersistentHashMap
user=> (eval m1)
{:a 1, :c 3, :b 2}
user=> (type *1)
clojure.lang.PersistentArrayMap
하지만를 ...
user=> (def m2 {:a ((fn [] 1)), :b 2, :c 3})
#'user/m2
user=> m2
{:a 1, :b 2, :c 3}
user=> (type m2)
clojure.lang.PersistentArrayMap
뭔가 다른 발견, 알고 보니는 알파벳에 따라 달라집니다 키의 순서, 아마도 그들이 어떻게 든 정렬되는 방식. 나는. aboce 예제에서 키가 {: d (스왑! ...) : a (keys ...)} 인 경우 동작이 다릅니다. – zenna
실제로 그것은 단지 그 행동이 이상하지 않고, 그것에 의존하지 않을 것입니다. – zenna
당신은 pdata-stats를 언급하고 있습니까? pdata-stats에 대한 인수는 변경할 수 없기 때문에 맵 키가 해당 함수 내에서 생성되는 순서는 무관합니다. – noisesmith