簡體   English   中英

clojure:with-redefs不能與clojure.core函數一起使用?

[英]clojure: with-redefs doesn't work with clojure.core functions?

我有一個關於with-redefs的問題。 以下示例無法按預期工作。 findmax ,總是調用clojure.core/max而不是with-redefs語句中的匿名函數。

(defn findmax [x y]
  (max x y))

(with-redefs (clojure.core/max (fn [x y] (- x y)))
  (findmax 2 5))

當我進行以下更改時,一切都按預期工作:

(defn mymax [x y]
  (max x y))

(defn findmax [x y]
  (mymax x y))

(with-redefs (my/max (fn [x y] (- x y)))
  (findmax 2 5))

我在這做錯了什么?

對於大於1的arity,Clojure編譯器會內聯max ,因此在編譯的代碼中沒有引用Var #'clojure.core/max ,也無法通過更改其來更改使用#'max的代碼片段的行為根綁定。 對於arity 1,這不會發生:

(defn my-max [& args] :foo)

(with-redefs [clojure.core/max my-max] (max 0))
;= :foo
(with-redefs [clojure.core/max my-max] (max 0 1))
;= 1
(with-redefs [clojure.core/max my-max] (max 0 1 2))
;= 2

;; and so on

這由鍵中的條目控制:inline:inline-arities max in source中的:inline-arities ; (source max)

clojure.core有很多自動內聯函數 - 主要是簡單的算術運算。 客戶端代碼可以自由定義新的(通過附加顯式:inline和可能:inline-arities元數據或使用definline )。 預期效果類似於定義宏,但內聯函數仍可用於高階用法。 重要的是要注意當前的實現有其驚喜(例如,參見Clojure JIRA中的CLJ-1227 ,以及與之相關的最新問題),因此在一天結束時,對於客戶端代碼,請謹慎使用常規宏和伴侶功能暫時可能是優選的。 將來,內聯函數很可能會被與編譯器宏配對的常規函數​​所取代 - 這就是ClojureScript模型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM