尝试在Clojure中使用redef函数时出现不一致

问题描述 投票:0回答:1

我正在和Clojure的with-redefs-fn玩耍,我发现一些令人困惑的不一致之处。例如:

(with-redefs-fn {#'println (constantly nil)} #(println "foo"))
=> nil

[如预期,println不再具有任何作用,仅相当于nil。但是,在:

(with-redefs-fn {#'= (constantly false)} #(= 1 1))
=> true

(with-redefs-fn {#'+ (constantly 0)} #(+ 1 1))
=> 2

(with-redefs-fn {#'max (constantly 1)} #(max 1 2))
=> 2

我们再也看不到预期的行为,重新定义的功能似乎照常运行。我怀疑这些特殊的简单功能已针对字节码操作进行了优化,因此不受重新定义的影响。任何人都可以确认这一点,因为它已经困扰了我一段时间。

clojure
1个回答
0
投票

有趣的是,如果您引用var而不是在函数调用位置,则会得到重新定义的值:

user=> (with-redefs-fn {#'= (constantly false)} #(constantly =)) 
#object[clojure.core$constantly$fn__5672 0x72458efc"clojure.core$constantly$fn__5672@72458efc"]
user=> =
#object[clojure.core$_EQ_ 0x2caf6912 "clojure.core$_EQ_@2caf6912"

这使得它绝对不是“参数列表长度”问题。绝对看起来像是某种内在的优化。

是,内联:https://github.com/clojure/clojure/blob/clojure-1.9.0/src/clj/clojure/core.clj#L976

© www.soinside.com 2019 - 2024. All rights reserved.