gpt4 book ai didi

clojure - clojure 的动态变量和绑定(bind)的实际目的是什么?

转载 作者:行者123 更新时间:2023-12-04 06:22:20 25 4
gpt4 key购买 nike

我看了一下引用资料:http://clojure.org/vars#Vars%20and%20the%20Global%20Environment , http://clojuredocs.org/clojure_core/clojure.core/binding

以及 clojure and ^:dynamicClojure Dynamic Binding

我还是不明白为什么需要binding完全因为我编写的每个程序都没有它们,我可以找到以传统方式编写示例的方法——我觉得这更容易理解。有没有利用这个的项目/编程范例的例子?

例如......在动物说话的例子中,你可以得到类似的效果:

(def dog {:name "Dog" :sound "Woof"})
(def cat {:name "Cat" :sound "Meow"})

(defn speak [animal]
(str (:name animal) " says " (:sound animal))

(println (speak dog))
(println (speak cat))

没有宏,没有动态绑定(bind)......仍然很干净。

最佳答案

严格来说并不需要它们:正如您正确地观察到的那样,您可以在没有 binding 的情况下做任何您想做的事情。 , 实际上如果 binding不存在,那么您可以使用宏和 Java 的 ThreadLocal 相对轻松地重新实现它。 s。

然而,绑定(bind)作为传递 的一种方式很有用。动态上下文 无需显式传递参数即可传递给函数。

当您编写深度嵌套的高阶函数并且不想向调用堆栈中的每个函数添加额外参数以便将一些值传递给嵌入深处的低级函数时,它特别有用。

以您的示例为基础:

(def ^:dynamic *loud-noises* false)

(defn speak [animal]
(str (:name animal) " says "
(let [sound (:sound animal)]
(if *loud-noises* (.toUpperCase sound) sound))))

(speak dog)
=> "Dog says Woof"

(binding [*loud-noises* true]
(speak dog))
=> "Dog says WOOF"

注意我不需要向 speak 添加额外的参数。函数来获得不同的行为。在这种情况下,添加一个额外的参数将是微不足道的,但想象一下,如果 speak函数被深埋在一个复杂的高阶函数中......

尽管如此,我认为总体上最好的建议是避免动态绑定(bind),除非你真的需要它。如果可以的话,通常最好添加显式参数:直接参数可以更容易地测试和推理函数。

关于clojure - clojure 的动态变量和绑定(bind)的实际目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12932530/

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