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