繁体   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