在Clojure中重新定义vars(脚本)



我正试图找到推迟var初始化的惯用方法(我确实希望它是不可变的)。

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

我知道Rich Hickey说重新定义是不习惯的。set!在这里合适吗?

我会使用delay:

获取一组表达式并生成一个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.
    ...
    ))

除了在Alex的回答中使用延迟之外,set!工作得很好,因为vars只是后台的javascript变量。

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

(defn foo [] release code here)

然后在一个只添加到调试构建的文件中:

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

最新更新