本文介绍了为什么Clojure defmulti调度函数收到0个参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

开始编辑:

Mea Culpa!抱歉。

Mea Culpa! I apologize.

我在Clojure 1.2.1的蛋糕中运行了此命令,说实话它没有用。现在它在退出cake repl和cake编译之后就可以了,它也可以在1.3.0上运行。

I was running this in the cake repl at Clojure 1.2.1, and it honestly did not work. Now it does after exiting cake repl and a cake compile, and it also works at 1.3.0.

结束编辑:

在以下情况中:我的调度函数正在传递零个参数,但我不知道为什么。我已经测试了调度功能,它可以完成预期的工作。我将不胜感激任何建议。

In the following: my dispatch function is being passed zero args, but I cannot figure out why. I've tested the dispatch function, and it does what it is supposed to. I would appreciate any suggestions.

(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


推荐答案

问题可能与未记录的 defonce defmulti 的类似行为。

The problem could perhaps be related to the undocumented defonce-like behavior of defmulti.

如果您重新加载包含( defmulti foo ...)格式,则 defmulti 不会被更新。这通常意味着将不更新调度功能,但是所有方法实现(在同一名称空间中)都将被更新。 ( defmulti foo ...)如果 foo var已绑定到值,则不执行任何操作。

If you reload a namespace that contains a (defmulti foo ...) form then that defmulti won't be updated. This often means that the dispatch function will not be updated but all method implementations (in the same namespace) will. (defmulti foo ...) does nothing if the foo var is already bound to a value.

要在REPL中解决此问题,请删除多方法var (ns-unmap'the.ns'-multimethod),然后重新加载名称空间(需要'the.ns:reload)

To fix this in a REPL, remove the multimethod var (ns-unmap 'the.ns 'the-multimethod) and then reload the namespace (require 'the.ns :reload).

为防止此问题,您可以定义调度分别运行,然后将其var传递给 defmulti ,像这样:

To prevent this problem you can define the dispatch function separately and pass its var to defmulti like this:

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

(defmulti foo #'foo-dispatch)

当代码如下所示时,如果对 foo-dispatch 进行更改,就足以重新加载名称空间。

When the code looks like this it's enough to reload the namespace if you make a change to foo-dispatch.

这篇关于为什么Clojure defmulti调度函数收到0个参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 02:44