[英]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.