Clojure中def和defonce有什么区别?

26

defdefonce在Clojure中有什么区别?

何时使用def,何时使用defonce

3个回答

36

defonce在变量已经定义时被跳过。

user> (def a 1) ;;=> #'user/a
user> a ;;=> 1
user> (def a 2) ;;=> #'user/a
user> a ;;=> 2
user> (defonce b 1) ;;=> #'user/b
user> b ;;=> 1
user> (defonce b 2) ;;=> nil
user> b ;;=> 1

8

如果名称没有根值,Defonce只会将名称绑定到根值。

例如,像Jay Fields blogs所述,当您想要重新加载命名空间但可能不需要全部重新加载时,可以与之配合使用。

(defonce ignored-namespaces (atom #{}))

(defn reload-all []   
  (doseq [n (remove (comp @ignored-namespaces ns-name) (all-ns))]
    (require (ns-name n) :reload )))

1

关于何时使用defonce,如果您正在使用带有热重载的系统(例如CLJS和mount以及re-frame),则defonce有助于在重新加载之间保持状态。

类似情况是当您自己重新评估源文件(例如在REPL中)但想要保留绑定到符号的变量值时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接