开始编辑:
Mea Culpa!我道歉。
我在Clojure 1.2.1的蛋糕代表中运行它,它老实说不起作用。现在它在退出蛋糕repl和蛋糕编译之后做了,它也在1.3.0工作。
结束编辑:
在下面:我的调度函数正在传递零参数,但我无法弄清楚原因。我已经测试了调度功能,它完成了应有的功能。我很感激任何建议。
(defrecord AcctInfo [acct-type int-val cur-bal])
(def acct-info (AcctInfo. \C 0.02 100.00))
ba1-app=> acct-info
ba1_app.AcctInfo{:acct-type \C, :int-val 0.02, :cur-bal 100.0}
(defn get-int-calc-tag [acct-type]
(cond (= acct-type \C) :checking
(= acct-type \S) :savings
(= acct-type \M) :moneym
:else :unknown))
(defmulti calc-int (fn [acct-info] (get-int-calc-tag (:acct-type acct-info))))
(defmethod calc-int :checking [acct-info] (* (:cur-bal acct-info) (:int-val acct-info)))
ba1-app=> (get-int-calc-tag (:acct-type acct-info))
:checking
ba1-app=> (calc-int acct-info)
java.lang.IllegalArgumentException: Wrong number of args (0) passed to: ba1-app$get-int-calc-tag
答案 0 :(得分:11)
问题可能与defonce
的无证defmulti
行为有关。
如果您重新加载包含(defmulti foo ...)
表单的命名空间,则defmulti
将不会更新。这通常意味着不会更新调度函数,但所有方法实现(在同一名称空间中)都将更新。 (如果defmulti foo ...)
var已绑定到值,则foo
不执行任何操作。
要在REPL中修复此问题,请删除multimethod var (ns-unmap 'the.ns 'the-multimethod)
,然后重新加载命名空间(require 'the.ns :reload)
。
要防止出现此问题,您可以单独定义调度功能,并将其var传递给defmulti
,如下所示:
(defn foo-dispatch [...]
...)
(defmulti foo #'foo-dispatch)
当代码看起来像这样时,如果您对foo-dispatch
进行更改,则足以重新加载命名空间。