当你不需要将某些东西定义为动态来重新定义它时,将某些东西定义为动态的重点是什么?

Dan*_*lan 17 clojure

在我看来,with-redefs可以做一切binding动态符号可以做的事情,只是它没有需要^:dynamic元数据的限制.那我什么时候应该使用另一个呢?

Ale*_*lex 17

除了需要^:dynamic元数据之外,binding还创建仅在当前线程with-redefs中可见的绑定,而由所做的绑定在所有线程中可见.因此,它with-redefs是一个非常生硬的工具,有可能影响在同一个VM中运行的其他代码.我从未见过with-redefs在测试代​​码之外使用,也不应该(至少在我看来).

我将总结两者之间的差异:

  • ^:dynamic 绑定允许您以受控方式引入一些动态行为.这是一种在API中定义扩展点的好方法,它允许远离调用链的调用者改变代码的行为,而不必在调用堆栈中一直显式地传递参数(其中一些甚至可能不是他们的代码).
  • with-redefs是一个免费的.它在测试中很有用,例如,当被测函数具有很多依赖性时,模拟整个子系统.

将var声明^:dynamic为使用耳罩来命名动态变量(例如*my-dynamic-var*)的惯例,还有一个额外的好处,即它是一种向呼叫者做广告的自我记录方式,可以动态修改代码的这一部分.

总结:在编写API和生产代码时,更喜欢^:动态绑定.在测试中使用with-redefs,并作为最后的手段动态地改变未声明的vars超出控件的行为^:dynamic(然后谨慎使用).