clojure - 为什么 Clojure defmulti 调度函数接收 0 个参数?

标签 clojure

开始编辑:

认罪!我道歉。

我在 Clojure 1.2.1 的 cake repl 中运行它,老实说它不起作用。现在它在退出 cake repl 和 cake compile 后就可以了,它也适用于 1.3.0。

结束编辑:

在下面:我的调度函数被传递了零参数,但我不知道为什么。我已经测试了 dispatch 函数,它做了它应该做的。如果有任何建议,我将不胜感激。

(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

最佳答案

这个问题可能与 defmulti 的未记录的 defonce 行为有关。

如果您重新加载包含 (defmulti foo ...) 形式的命名空间,则该 defmulti 将不会更新。这通常意味着分派(dispatch)函数不会更新,但所有方法实现(在同一命名空间中)都会更新。 (defmulti foo ...) 如果 foo var 已经绑定(bind)到一个值,则不执行任何操作。

要在 REPL 中修复此问题,请删除 multimethod var (ns-unmap 'the.ns 'the-multimethod) 然后重新加载命名空间 (require 'the.ns :reload )

为了防止这个问题,你可以单独定义调度函数并将其 var 传递给 defmulti,如下所示:

(defn foo-dispatch [...]
  ...)

(defmulti foo #'foo-dispatch)

当代码看起来像这样时,如果您对 foo-dispatch 进行更改,则足以重新加载命名空间。

关于clojure - 为什么 Clojure defmulti 调度函数接收 0 个参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8565044/

相关文章:

algorithm - 在 Clojure 中实现 Minimax 算法 - 具有多个递归调用的条件函数

clojure - 定义 Clojure 多方法

clojure - Clojure 的 SSE(服务器发送事件)客户端库?

java - 使用 clojure 中的 java api 读取 zip 文件

clojure - 在 Clojure 中导入什么 -?> ?

clojure - 在《The Joy of Clojure》中的 contextual-eval 中取消引用构造

recursion - 如何在 Clojure 中生成内存递归函数?

mysql - 我应该如何处理 clojure 项目的 sql 模式管理?

clojure - 调用 shutdown-agents 后重新启动代理线程池

java - 对于与 Doseq(和方法代码太大)