clojure—本地重写运算符的正确方法,例如+&引用&引用*&引用;,等

clojure—本地重写运算符的正确方法,例如+&引用&引用*&引用;,等,clojure,overriding,Clojure,Overriding,重写像“+”这样的方法的正确方法是什么?现在我有 (defn- + [x y] (replacement x y)) 但这会导致命令行上出现警告 WARNING: + already refers to: #'clojure.core/+ in namespace: <MY-NAMESPACE>, being replaced by #'<MY-NAMESPACE>/+ WARNING:+已在命名空间中引用:#'clojure.core/+,替换为#'/+ 您确定要执

重写像“+”这样的方法的正确方法是什么?现在我有

(defn- + [x y] (replacement x y))
但这会导致命令行上出现警告

WARNING: + already refers to: #'clojure.core/+ in namespace: <MY-NAMESPACE>, being replaced by #'<MY-NAMESPACE>/+
WARNING:+已在命名空间中引用:#'clojure.core/+,替换为#'/+

您确定要执行此操作吗?如果是,您可以使用defprotocol指定要覆盖的运算符,并扩展要实现这些覆盖的类。关于一个(人为的)示例,请参见我的

,虽然我不建议覆盖像+,但您可以使用binding或let,这取决于您想要的行为:

(let [+ -] (redu­ce + [1 2 3])) ; -4 
(defn my-pl­us [x] (redu­ce + x))
(let [+ -] (my-p­lus [1 2 3])) ;6
(binding [+ -] (my-p­lus [1 2 3])); -4
正如在下面的评论中所说的,自从clojure 1.3以来,绑定不再以这种方式工作,因为var应该是动态的,+,-等等不是

然而,出于测试目的/嘲笑,您可能会得到类似的行为。在这种情况下,看看redefs(从clojure 1.3开始):

另见:

您还可以使用contrib的通用接口覆盖内置算法,请参见下面的简单示例


您需要排除由core导入的函数:

 (ns your-ns
   (:refer-clojure :exclude [+ ...]))

 (defn + ...)

无法在clojure 1.3下工作-“+”未标记为动态,无法重新启动-bound@aav-对于绑定来说可能是正确的,但是let版本应该仍然有效(因为let是一种词汇绑定)是的,我确定,我正在尝试编写DSL。很好的解决方案,谢谢!需要明确的是,对于那些新加入Clojure的人来说,这个问题不是面向对象意义上的“覆盖”(Clojure不是面向对象的)。真正的问题是如何防止在全局var反弹时触发的警告。第一个绑定发生是因为使用
ns
宏从clojure.core引入映射。(请参阅)第二个绑定发生在本地文件重新绑定变量时。此外,还有更多术语:Clojure没有方法。它有很多功能。