2017-04-11 68 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的值。