关于类OR关键字的Clojure multimethod

时间:2011-03-23 18:24:37

标签: clojure multimethod

假设我有这种多方法

(defmulti m (fn [v] [(:type v)]))

(defmethod m [Object] [k] (prn "Object"))

(defmethod m [:mykwd] [k] (prn "mykwd"))

当我用Object的子类调用它时,它会正确地调度到第一个实现:

(m {:type String})
"Object"

使用:mykwd它也可以按预期工作:

(m {:type :mykwd})
"mykwd"

但是当我提供另一个关键字时,我得到一个例外:

(m {:type :anotherkwd})
#<CompilerException java.lang.IllegalArgumentException: No method in multimethod 'm'
for dispatch value: [:anotherkwd] (NO_SOURCE_FILE:0)>

这个调度究竟是如何运作的?

是否可以为类继承保留此行为,并且仍然具有捕获所有关键字的“默认”实现?

编辑这个例子很简单,但我需要它来处理二进制函数。我的真正需求如下。我不知道如何将:default应用于它。

(defmulti m (fn [arg mp] [(class arg) (:type mp)]))

然后我正在寻找一种方法来定义argnil(:type mp)为什么的情况。这适用于:type的值是一个类,但不适用于任何关键字:

(defmethod m [nil Object] [arg mp] (prn "Whatever"))

2 个答案:

答案 0 :(得分:5)

有一个默认值:

(defmethod m :default [x] :oops)

参考:

点击页面底部的http://clojure.org/multimethods

答案 1 :(得分:2)

尝试使用自定义函数替换:type调度,该函数在:typenil时返回默认值。 class也是如此。然后你可以发送一个关键字矢量。如果需要继承行为,请将关键字添加到层次结构中。