【问题标题】:var versus atom for runtime constantsvar 与 atom 用于运行时常量
【发布时间】:2013-01-14 04:45:18
【问题描述】:

基于命令行输入,我需要设置一些运行时常量,许多下游函数将使用这些常量。这些函数中的代码可能在其他线程中执行,所以我不考虑“声明 var 并使用绑定宏”组合。与使用原子相比,使用 var(带有 alter-var-root)的优点/缺点是什么?也就是说,

(declare *dry-run*) ; one of my constants

(defn -main [& args]
   ; fetch command line option
   ;(cli args ...)
   (alter-var-root #'*dry-run* (constantly ...))
   (do-stuff-in-thread-pool))

对

(def *dry-run* (atom true))   

(defn -main [& args]
   ; fetch command line option
   ;(cli args ...)
   (reset! *dry-run* ...)
   (do-stuff-in-thread-pool))

如果除了这两个之外还有其他我应该考虑的选择,我很想知道。

另外,理想情况下,我宁愿不向 atom 提供初始 val,因为我想在其他地方设置默认值(使用 cli 调用),但我可以忍受它,特别是如果使用 atom 提供的优势相比替代品。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    一次性写入值正是为用例设计的承诺:

    (def dry-run (promise))
    
    (defn -main []
      (deliver dry-run true))
    
    (defn whatever [f]
      (if @dry-run
        ...))
    

    【讨论】:

    • 感谢您的提示。传递给 promise 的值是否会在所有线程中可见(自动绑定传输),还是我需要为此做一些特殊的事情?
    • 除了 vars 之外,绑定传输根本不进入图片。 Promise 只是一个 Clojure 对象,当它被取消引用时,将产生传递给它的值,或者阻塞直到这样的值到达。如果你定义了一个全局哈希映射,线程的相关性并不高。
    • 谢谢。由于我的值是一个运行时常量,因此它可以作为一次写入值。
    【解决方案2】:

    AFAIK alter-var-root 仅保证同步变量值更改,不保证在此更改期间安全读取。另一方面,atom 确实提供了以原子方式更改身份状态。

    如果您不想提供初始值,可以将其设置为 nil:

    (def *dry-run* (atom nil)) 
    

    【讨论】:

      【解决方案3】:

      仅使用 var 和 alter-var-root 有什么问题?在真正启动工作人员之前,您在启动函数中设置了新值。所以阅读没有种族。您可以将@ 保存在您需要该值的任何地方。

      【讨论】:

        猜你喜欢
        • 2013-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-30
        • 1970-01-01
        • 1970-01-01
        • 2014-10-24
        • 2022-01-17
        相关资源
        最近更新 更多