Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
扩展交换!Clojure中nil型的行为_Clojure - Fatal编程技术网

扩展交换!Clojure中nil型的行为

扩展交换!Clojure中nil型的行为,clojure,Clojure,假设我有var原子var (def atom-val (atom [])) 还假设原子的标准行为: (swap! atom-val conj {:b "2"}) => #object[clojure.lang.Atom 0x6500d3fd {:status :ready, :val [{:a "2"}] (@atom-val) => #object[clojure.lang.Atom 0x6500d3fd {:status :ready, :val [{:a "2"}] 我希望

假设我有var原子var

(def atom-val (atom []))
还假设原子的标准行为:

(swap! atom-val conj {:b "2"})
=> #object[clojure.lang.Atom 0x6500d3fd {:status :ready, :val [{:a "2"}]
(@atom-val)
=> #object[clojure.lang.Atom 0x6500d3fd {:status :ready, :val [{:a "2"}]
我希望创建与使用nil对象相同的行为,但不执行操作:

(def atom-val nil)
(swap! atom-val conj "New val")
当然,我会得到一个NullPointerException。但我希望什么都没发生,就这样吧。我不需要每次都写尝试,我只需要描述的行为

我明白了!是函数,atom是函数,atom返回clojure.lang.IAtom,clojure.lang.IAtom是接口。我无法扩展接口。 如何获得所描述的行为

我有一个全局动态变量,它等于零

(def ^:dynamic  atom-val nil). 
每当使用compojure创建线程的环处理程序时,我都将atom val绑定到

(defn func [handler] 
   (fn [request]
     (binding [atom-val (atom [])]
        (handler request)
    )
 )
因此,我在不同的功能中有这样一种形式:

(swap! atom-val conj "New val"). 
我可以在不同功能的内部/外部到处运行它很多次。每次检查atom val是否为null都非常糟糕。函数必须进行交换!,但有时,当函数进行交换时,atom val无法正确初始化!外环处理器,在绑定之前

所以我决定这样做:我想扩展交换!原子的协议,当传递原子值为nil时,它不能抛出NullPointerException。

您需要使用fnil。看

例如:

(def atom-val nil)
(def nil-swap! (fnil swap! (atom [])))

(nil-swap! atom-val conj "New val") => ["New val"]
别忘了随时打开浏览器选项卡

所以,你想交换!零分?我不知道你的行动和无所事事是什么意思

至少对我来说,交换是毫无意义的!零值;如果它对你有影响,你应该回顾一下原子到底是什么。也许你的意思是,当给定nil而不是atom引用时,交换就发生了!我什么也不做

如果是这样的话,您只需使用自己的函数为您执行该检查:

(defn nilable-swap!
  [a f]
  (when a (swap! a f)))
但我真的不建议你这样做,如果这是你想做的,这是一个坏的设计和控制流的迹象。当然,如果你不确定的话,检查原子引用是否为零是有意义的,但是你真的需要例行检查吗?你真的不知道你得到了原子引用吗


我想我可能已经回答了你的问题,但如果我误解了,请随时澄清,我会更新/删除答案。

如果你想要一个什么都不做的原子,你可以写:

(def noop-atom
  (reify clojure.lang.IAtom
    (reset [_ _])
    (swap [_ _])
    (swap [_ _ _])
    (swap [_ _ _ _])
    (swap [_ _ _ _ _])
    (compareAndSet [_ _ _])))
然后,您可以使用这个原子作为动态变量的根值


如果您的目标是在响铃请求/响应的生命周期内管理状态,您可以编写一个自定义。

可以询问此替换的目的吗?谢谢,您已经给出了正确的答案。然后我找到了deref协议。