Clojure 中的 def 和 defonce 有什么区别?
What is the difference between def and defonce in Clojure?
Clojure 中的 def 和 defonce 有什么区别?
何时使用 def 而不是 defonce 或相反?
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
如果名称没有根值,Defonce 只会将名称绑定到根值。
比如像Jay Fields blogsabout,当你想重新加载命名空间但可能不需要全部重新加载时,它可以结合使用。
(defonce ignored-namespaces (atom #{}))
(defn reload-all []
(doseq [n (remove (comp @ignored-namespaces ns-name) (all-ns))]
(require (ns-name n) :reload )))
至于什么时候使用defonce
,如果你正在使用带热重载的系统(例如带挂载的 CLJS 和 re-frame),defonce
有助于保持状态在重新加载之间。
当您自己 re-evaluate 源文件(例如在 REPL 中)但希望将 var 的值保持绑定到符号时的类似情况。
Clojure 中的 def 和 defonce 有什么区别?
何时使用 def 而不是 defonce 或相反?
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
如果名称没有根值,Defonce 只会将名称绑定到根值。
比如像Jay Fields blogsabout,当你想重新加载命名空间但可能不需要全部重新加载时,它可以结合使用。
(defonce ignored-namespaces (atom #{}))
(defn reload-all []
(doseq [n (remove (comp @ignored-namespaces ns-name) (all-ns))]
(require (ns-name n) :reload )))
至于什么时候使用defonce
,如果你正在使用带热重载的系统(例如带挂载的 CLJS 和 re-frame),defonce
有助于保持状态在重新加载之间。
当您自己 re-evaluate 源文件(例如在 REPL 中)但希望将 var 的值保持绑定到符号时的类似情况。