gpt4 book ai didi

clojure - 使用 "def"更新 var 和 "alter-var-root"之间的区别

转载 作者:行者123 更新时间:2023-12-02 11:30:24 24 4
gpt4 key购买 nike

使用“def”更新 var 和使用“alter-var-root”有什么区别?例如

(def x 3)
(def x (inc x))

对比

(def x 3)
(alter-var-root #'x inc)

最佳答案

我发现 alter-var-root 很少出现在惯用的 Clojure 代码中;并不是说它有什么问题,它只是针对极端情况。如果您发现自己使用它来构建循环,那么这表明需要采取不同的方法。我主要在用于设置访问凭据或记录器等的初始化例程中看到它。

alter-var-root使用函数机械地更改 var 的值,而 def只需将其设置为新值即可。在您的示例中,它们是等效的。

hello.exp> (def foo 4)
#'hello.exp/foo
hello.exp> (alter-var-root #'foo inc)
5
hello.exp> foo
5

alter-var-root也不愿意创建新的var:

hello.exp> (alter-var-root #'foo1 inc) 
CompilerException java.lang.RuntimeException: Unable to resolve var: foo1 in this context, compiling:(NO_SOURCE_PATH:1)

alter-var-root也可以在其他命名空间上工作:

hello.exp> (in-ns 'user)
#<Namespace user>
user> (alter-var-root #'hello.exp/foo inc)
6
user> (def hello.exp/foo 4)
CompilerException java.lang.RuntimeException: Can't create defs outside of current ns, compiling:(NO_SOURCE_PATH:1)
user>

最后一个用例是我在实践中唯一需要的用例。例如强制clojure.logging使用正确的 slf4j 记录器作为 Pallet 项目中的示例:

(defn force-slf4j
"The repl task brings in commons-logging, which messes up our logging
configuration. This is an attempt to restore sanity."
[]
(binding [*ns* (the-ns 'clojure.tools.logging.slf4j)]
(alter-var-root
#'clojure.tools.logging/*logger-factory*
(constantly (clojure.tools.logging.slf4j/load-factory)))))

这只是使用 alter-var-root重置另一个命名空间中的 var,无论初始化时的内容如何。我想这有点像黑客......

关于clojure - 使用 "def"更新 var 和 "alter-var-root"之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16447621/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com