2017-04-11 77 views

回答

4

它们基本上是一样的,主要区别是with-redefs可以让你明确地写出正文(如在let中),而with-redefs-fn需要一个函数作为参数,所以你可能需要包装你想要的东西拉姆达。此外,with-redefs允许您使用矢量提供绑定(再次,如let),而with-redefs-fn需要地图。我认为这些差异只是肤浅的。

例如

(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

2

我会忽略with-redefs-fn并且只使用with-redefs,因为它更简单并且具有相同的能力。另外,请注意,符号#'http/post要求您使用var代替http/post,而不是函数本身。

有关Clojure var如何工作的说明,请参阅此问题:When to use a Var instead of a function?它类似于C指针。

在clojure中,当您看到foo时,它是一个符号。当您看到#'foo时,它是(var foo)的一种快捷方式,它是一种“特殊形式”(即Clojure内置函数,不是常规函数),它返回varfoo指向的点。 var又指示foo的值。