【问题标题】:Re-def vars in Clojure(script)Clojure 中的重新定义变量(脚本)
【发布时间】:2014-04-18 15:03:52
【问题描述】:

我正在尝试找到一种惯用的方式来推迟 var 的初始化(我真的打算让它不可变)。

(def foo nil)
...
(defn init []
  ; (def foo (some-function))
  ; (set! foo (some-function)))

我知道 Rich Hickey 说过 re-defing isn't idiomaticset! 在这里合适吗?

【问题讨论】:

    标签: clojure clojurescript


    【解决方案1】:

    我会使用delay:

    接受一个表达式体并产生一个延迟对象,它将 仅在第一次强制时调用主体(使用 force 或 deref/@),并且 将缓存结果并在所有后续强制中返回它 来电。另请参阅 - 实现了吗?

    示例用法:

    (def foo (delay (init-foo))) ;; init-foo is not called until foo is deref'ed
    
    (defn do-something []
      (let [f @foo] ;; init-foo is called the first time this line is executed,
                    ;; and the result saved and re-used for each subsequent call.
        ...
        ))
    

    【讨论】:

      【解决方案2】:

      除了像亚历克斯在他的回答中所说的那样使用延迟之外,设置!工作得很好,因为 vars 只是底层的 javascript 变量。

      你的不应该真的直接设置!像这样的 vars,但是对于像这样的特殊情况,我个人允许自己(谨慎地)这样做(即数据实际上是正常的不可变 Clojure 一旦设置)。我这样做的一个例子是在调试版本中覆盖函数:

      (defn foo [] release code here)
      

      然后在仅添加到调试版本的文件中:

      (defn debug-foo []
        (.log js/console "foo called"))
      (set! foo debug-foo)
      

      【讨论】:

      • 我想知道在调试版本中修改代码的做法有哪些。感谢您分享!
      • 奇怪的是,set! 在 ClojureScript 中适用于 var,但不适用于 Clojure。
      • set! 在 ClojureScript 中工作,因为它用于改变 javascript 变量 - ClojureScript 中的“vars”不是 Var 的; Clojure 的 Var 不存在于 ClojureScript 中,也不支持变异。在 Clojure 中,您不会改变“变量”——您将它们绑定到名称或使用 refs/atoms/agents。在 ClojureScript 中,set! 直接改变 Javascript 变量。在某种程度上,我想能够像这样使用set! 是 ClojureScript 实现的产物,尽管我不知道它是否是这样计划的。希望这是有道理的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 2016-06-03
      • 1970-01-01
      • 2014-12-25
      • 2019-05-27
      • 1970-01-01
      相关资源
      最近更新 更多