作为其他值的容器,也都可以解引用。
deref不会阻塞。
add-watch
(add-watch reference key fn)
可以定义引用值发生改变时的回调,fn是4个参数 :key (atom/var/agent) 旧状态 新状态
(def a (atom {}))
(add-watch a :watcher
(fn [key atom old-state new-state]
(prn "-- Atom Changed --")
(prn "key" key)
(prn "atom" atom) (prn "old-state" old-state) (prn "new-state" new-state))) (reset! a {:foo "bar"}) ;; "-- Atom Changed --" ;; "key" :watcher ;; "atom" #<Atom@4b020acf: {:foo "bar"}> ;; "old-state" {} ;; "new-state" {:foo "bar"} ;; {:foo "bar"}
watcher在每次修改时都会被调用,但是不保证真的有改变。因此可能需要自己比较新旧值
key用于给1个ref上添加多个不同watcher,移除watcher也要用key
(remove-watch reference key)
atom
用swap! 修改
;; make an atomic list (def players (atom ())) ;; #'user/players ;; conjoin a keyword into that list (swap! players conj :player1) ;;=> (:player1) ;; conjoin a second keyword into the list (swap! players conj :player2) ;;=> (:player2 :player1) ;; take a look at what is in the list (deref players) ;;=> (:player2 :player1)
swap! 接受函数 和参数,把atom里的作为第1个参数。后面参数不限
如果f的过程复杂,比如comp 几个函数计算时间会长, 在这期间atom的值可能被修改,而如果使用atom的老值计算,但是返回前atom改成了新值,此时,老值的计算结果会被放弃。
可以强行reset!