我正试图找到推迟var初始化的惯用方法(我真的打算成为不可变的)。
(def foo nil)
...
(defn init []
; (def foo (some-function))
; (set! foo (some-function)))
我知道Rich Hickey说re-defing isn't idiomatic。这里set!
是否合适?
答案 0 :(得分:5)
我会使用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.
...
))
答案 1 :(得分:1)
除了在Alex的回答中使用延迟时,请设置!工作正常,因为变量只是引擎盖下的javascript变量。
Yous 不应该真正直接设置!像这样的变量,但对于像这样的特殊情况,我个人允许自己(谨慎地)这样做(即数据实际上是正常的不可变Clojure一旦设置)。我这样做的一个例子是覆盖调试版本中的函数:
(defn foo [] release code here)
然后在仅添加到调试版本的文件中:
(defn debug-foo []
(.log js/console "foo called"))
(set! foo debug-foo)