clojure - 本地覆盖运算符的正确方法,如“+”,“*”等

时间:2011-06-27 06:58:21

标签: clojure override

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

(defn- + [x y] (replacement x y))

但这会在命令行上产生警告。

WARNING: + already refers to: #'clojure.core/+ in namespace: <MY-NAMESPACE>, being replaced by #'<MY-NAMESPACE>/+

4 个答案:

答案 0 :(得分:33)

您需要排除核心导入的功能:

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

 (defn + ...)

答案 1 :(得分:4)

虽然我不建议覆盖像+这样的核心功能,你可以使用绑定或者为此,它取决于你想要的行为:

(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应该是动态的,+, - 等不是。

出于测试目的/模拟,您可以获得类似的行为。在这种情况下,请查看with-redefs(从clojure 1.3开始): http://clojuredocs.org/clojure_core/clojure.core/with-redefs

另见: Let vs. Binding in Clojure

答案 2 :(得分:3)

你确定要这么做吗?如果是,则可以使用defprotocol指定要覆盖的运算符,并扩展要为其实现这些覆盖的类。对于(人为的)示例,请参阅我的answer to this question.

答案 3 :(得分:1)

您还可以使用contrib中的通用接口覆盖内置算术,请参阅以下内容以获取一个简单示例

http://nakkaya.com/2010/08/02/using-clojure-contrib-generic-interfaces/