2015-08-31 34 views
1

我想assoc將地圖的iate值轉換爲​​。 我能做到這一點,如:Clojure交換原子與地圖值

(defonce config (atom {})) 
    (swap! config assoc :a "Aaa") 
    (swap! config assoc :b "Bbb") 

但它是重複的,並且使得多次打電話給swap!。 我願做這樣的事情:

(swap! config assoc {:a "Aaa" 
         :b "Bbb"}) 
;; this doesn't work : 
;; Exception in thread "main" clojure.lang.ArityException: Wrong number of args (2) passed to: core$assoc 

我該怎麼辦呢?

回答

5

查看文檔assoc

=> (doc assoc) 
------------------------- 
clojure.core/assoc 
([map key val] [map key val & kvs]) 
    assoc[iate]. When applied to a map, returns a new map of the 
    same (hashed/sorted) type, that contains the mapping of key(s) to 
    val(s). When applied to a vector, returns a new vector that 
    contains val at index. Note - index must be <= (count vector). 
nil 

assoc不帶地圖。這需要鑰匙對和丘壑:

user=> (assoc {} :a 1 :b 2) 
{:a 1, :b 2} 
user=> (let [x (atom {})] 
        #_=> (swap! x assoc :a 1 :b 2) 
        #_=> x) 
#object[clojure.lang.Atom 0x227513c5 {:status :ready, :val {:a 1, :b 2}}] 

順便說一句,你應該總是隔離您的更新,以原子爲單個swap!。通過如上所述進行兩次交換,您允許其他線程潛在地破壞引用的數據。一個swap!保持一切原子。


N.B.merge表現得像你想像的那樣:

user=> (merge {} {:a 1 :b 1}) 
{:a 1, :b 1} 
user=> (let [x (atom {})] 
        #_=> (swap! x merge {:a 1 :b 2}) 
        #_=> x) 
#object[clojure.lang.Atom 0x1be09e1b {:status :ready, :val {:a 1, :b 2}}]