我正试图找到推迟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)