我对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))
我在这里做错了什么?
答案 0 :(得分:8)
max
,因此在编译的代码中没有对Var #'clojure.core/max
的引用,也无法更改使用{的代码片段的行为{1}}通过更改其根绑定。对于arity 1,这不会发生:
#'max
这由(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
。
(source max)
中有很多自动内联函数 - 主要是简单的算术运算。客户端代码可以自由定义新的(通过附加显式clojure.core
和可能的:inline
元数据或使用:inline-arities
)。预期效果类似于定义宏,但内联函数仍可用于高阶用法。重要的是要注意当前的实现有其惊喜(例如,参见Clojure JIRA中的CLJ-1227,以及与之相关的最新问题),因此在一天结束时,对于客户端代码,仔细使用常规宏和伴随函数可能暂时是优选的。将来,内联函数很可能会被与编译器宏配对的常规函数所取代 - 这就是ClojureScript模型。