我正在动态注册一个符号,我可以验证它是否成功:
(defn- register[x]
(intern 'foo.core x (atom {}))
(println "Var " x " gets " (var-get (get (ns-interns 'foo.core) x))))
; Var Persons gets #object[clojure.lang.Atom 0x688a2c09 {:status :ready, :val {}}]
我的核心问题是:如何使用x(swap!...
第二个问题是:如何取消引用x来获取地图本身?
最后一个问题是:有更清洁的方法吗?
intern
函数返回一个variable
对象,因为它是一个参考值,它可以被解引用(使用@
或deref
)。它也可以从功能返回并进行操作,以获得所需的结果。此var指向的值(或var的绑定)指向一个原子,这是另一个参考值,也可以取消引用。
这是一个如何处理这种情况的小例子:
user> (ns my.ns)
nil
my.ns> (in-ns 'user)
#namespace[user]
user> (defn register-trace [v-name]
(let [v (intern 'my.ns v-name (atom {}))]
(println (str "v is " v))
(println (str "v's contents is " @v))
(println (str "v's internal value is " @@v))
v))
#'user/register-trace
user> (register-trace 'asd)
;;=> v is #'my.ns/asd
;;=> v's contents is clojure.lang.Atom@6a6ee04b
;;=> v's internal value is {}
#'my.ns/asd
user> (let [var-atom @(register-trace 'my-var)]
(swap! var-atom assoc :x 101))
;;=> v is #'my.ns/my-var
;;=> v's contents is clojure.lang.Atom@2164d9ed
;;=> v's internal value is {}
{:x 101}
user> @my.ns/my-var
{:x 101}
user> (swap! my.ns/my-var update :x inc)
{:x 102}
user> @my.ns/my-var
{:x 102}