首页 > 其他 > 详细

Clojure的引用类型:var,ref,agent和atom

时间:2019-06-04 13:37:17      阅读:124      评论:0      收藏:0      [点我收藏+]

作为其他值的容器,也都可以解引用。

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!

 

 

Clojure的引用类型:var,ref,agent和atom

原文:https://www.cnblogs.com/xuanmanstein/p/10972875.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!