我想了解with-redefs
和with-redefs-fn
之间的区别。
具体的例子可以很好地理解fns的行为。
答案 0 :(得分:11)
它们基本相同,主要区别在于with-redefs
允许您明确地写出正文(如let
中),而with-redefs-fn
需要函数作为参数,所以你可能需要在lambda中包装你想要的东西。此外,with-redefs
允许您使用向量提供绑定(同样,如let
),而with-redefs-fn
则需要地图。我认为这两种差异都只是肤浅的。
e.g。
(with-redefs [http/post (fn [url] {:body "Goodbye world"})]
(is (= {:body "Goodbye world"} (http/post "http://service.com/greet"))))
vs
(with-redefs-fn {#'http/post (fn [url] {:body "Goodbye world"})}
(fn [] (is (= {:body "Goodbye world"} (http/post "http://service.com/greet")))))
事实上,with-redefs
是根据with-redefs-fn
定义的,基本上只是在将所有内容传递给with-redefs-fn
之前将主体包装在匿名函数中:https://github.com/clojure/clojure/blob/e3c4d2e8c7538cfda40accd5c410a584495cb357/src/clj/clojure/core.clj#L7404
答案 1 :(得分:5)
我会忽略with-redefs-fn
并仅使用with-redefs
,因为它更简单且具有相同的能力。另外,请注意,符号#'http/post
要求您使用http/post
的var,而不是函数本身。
有关Clojure var
如何工作的说明,请参阅此问题:When to use a Var instead of a function?它类似于C指针。
在clojure中,当你看到foo
时,它就是一个符号。当您看到#'foo
时,它是(var foo)
的快捷方式,它是一种“特殊形式”(即内置的Clojure,而不是常规函数),它返回var
foo
{1}}指向。 var
依次指向foo
的值。