简体   繁体   English

clojure:with-redefs不能与clojure.core函数一起使用?

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

I've a question about with-redefs . 我有一个关于with-redefs的问题。 The following example doesn't work as expected. 以下示例无法按预期工作。 In findmax , clojure.core/max is always called instead of the anonymous function in the with-redefs statement. 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))

When I make the following changes everything works as expected: 当我进行以下更改时,一切都按预期工作:

(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))

What am I doing wrong here? 我在这做错了什么?

max is inlined by the Clojure compiler for arities greater than 1, so there is no reference to the Var #'clojure.core/max in the compiled code and no way to change the behaviour of code fragments that use #'max by changing its root binding. 对于大于1的arity,Clojure编译器会内联max ,因此在编译的代码中没有引用Var #'clojure.core/max ,也无法通过更改其来更改使用#'max的代码片段的行为根绑定。 For arity 1, this does not happen: 对于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

This is controlled by the entries at keys :inline and :inline-arities in the source of max ; 这由键中的条目控制:inline:inline-arities max in source中的:inline-arities ; see (source max) . (source max)

There are quite a few automatically inlined functions in clojure.core -- mostly the simple arithmetic operations. clojure.core有很多自动内联函数 - 主要是简单的算术运算。 Client code is free to define new ones (by attaching explicit :inline and possibly :inline-arities metadata or by using definline ). 客户端代码可以自由定义新的(通过附加显式:inline和可能:inline-arities元数据或使用definline )。 The expected effect is similar to defining a macro, except an inlined function is still available for higher-order usage. 预期效果类似于定义宏,但内联函数仍可用于高阶用法。 It's important to note that the current implementation has its surprises (see CLJ-1227 in the Clojure JIRA, for example, and the more recent issues linked therefrom), so at the end of the day, for client code, careful use of regular macros and companion functions is likely to be preferable for the time being. 重要的是要注意当前的实现有其惊喜(例如,参见Clojure JIRA中的CLJ-1227 ,以及与之相关的最新问题),因此在一天结束时,对于客户端代码,请谨慎使用常规宏和伴侣功能暂时可能是优选的。 In the future, inlined functions may well be replaced by regular functions paired with compiler macros -- this is the ClojureScript model. 将来,内联函数很可能会被与编译器宏配对的常规函数​​所取代 - 这就是ClojureScript模型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM