【问题标题】:Extend swap! behaviour for nil type in Clojure延长交换! Clojure 中 nil 类型的行为
【发布时间】:2019-01-23 15:58:06
【问题描述】:

让假设,我有变种原子-VAR P>

(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"}]

我要创建相同的行为,因为它会与零的目标工作,但没有行动: P>

(def atom-val nil)
(swap! atom-val conj "New val")

当然,我会得到一个NullPointerException。但我想什么都没有发生,剿它。我不需要写尝试每一次,我只需要描述behavuiour。 P>

我看到的交换的是一个函数,原子 EM>是一个函数,返回原子 clojure.lang.IAtom EM>,clojure.lang。 IAtom是一个接口。我不能扩展接口。 我怎样才能描述的行为? P>

好,我有一个全球性的动态变量,其等于零 P>

(def ^:dynamic  atom-val nil). 

每当一个线程被创建(它与环的Compojure处理程序),我绑定原子-VAL到 P>

(defn func [handler] 
   (fn [request]
     (binding [atom-val (atom [])]
        (handler request)
    )
 )

所以,我有在不同的功能这样的形式:

(swap! atom-val conj "New val"). 

我随处运行了很多次(内/外不同的功能)。这是非常糟糕的检查每一个时间是否原子-VAL STRONG>为空或不是。功能的有无以使交换的,但有时原子-VAL EM>不能被正确初始化(当一个函数使得交换!外侧环处理程序,结合前)。

所以我决定做这样说:我想延长的交换 em>的协议为Atom和为零时(当atom-val中的无 em>的)传递!它必须不抛出NullPointerException。

【问题讨论】:

  • 一个可以询问什么是这种替代的目的是什么?跨度>

标签: clojure


【解决方案1】:

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

(def noop-atom
  (reify clojure.lang.IAtom
    (reset [_ _])
    (swap [_ _])
    (swap [_ _ _])
    (swap [_ _ _ _])
    (swap [_ _ _ _ _])
    (compareAndSet [_ _ _])))

然后你可以使用这个原子作为动态变量的根值。

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

【讨论】:

  • 谢谢,您给出了正确答案。然后我还发现了 deref 协议。
【解决方案2】:

您需要使用fnil。见https://clojuredocs.org/clojure.core/fnil

例子:

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

(nil-swap! atom-val conj "New val") => ["New val"]

别忘了让浏览器选项卡始终对The Clojure CheatSheet 保持打开状态!

【讨论】:

    【解决方案3】:

    那么,你想swap! 零?我不确定你所说的行动和什么都不做是什么意思。

    swap! 一个 nil 值绝对没有意义(至少对我而言);如果它对你有用,你应该回顾一下原子到底是什么。也许你的意思是当给定一个 nil 而不是一个原子引用时,swap! 不会做任何事情。

    如果是这样,那么您可以创建自己的函数来为您进行检查:

    (defn nilable-swap!
      [a f]
      (when a (swap! a f)))
    

    但是我真的不建议你这样做,如果这是你想做的,这表明设计和控制流程不好。当然,如果您不确定,检查您的 atom 引用是否为 nil 确实有意义,但您真的需要定期检查吗?真的没有一点你知道你得到了你的原子参考吗?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      • 2021-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多