2016-09-30 55 views
0

我已经在clojure中编写了这个多功能函数。使用defmulti调度功能的问题

(defmulti printlmt (fn [s] (> (count s) 10))) 
(defmethod printlmt true [s] (println s)) 
(defmethod printlmt false [s] (println (take 10 s))) 

然后我尝试如下执行它..

(printlmt "test") 

不过,我不断收到以下错误。

IllegalArgumentException No method in multimethod 'printlmt' for dispatch value: 4 clojure.lang.MultiFn.getFn (MultiFn.java:156) 

在我的理解中,匿名函数应返回值true。为什么匿名函数返回4?

如果我单独叫调度功能,这样

((fn [s] (> (count s) 0)) "test") 

在这种情况下,它会返回true

编辑: 我加入,我有终端文本:

startingclojure.core=> (defmulti printlmt (fn [s] (> (count s) 10))) 
nil 
startingclojure.core=> (defmethod printlmt true [s] (println s)) 
#object[clojure.lang.MultiFn 0x3315fe88 "[email protected]"] 
startingclojure.core=> (defmethod printlmt false [s] (println (take 10 s))) 
#object[clojure.lang.MultiFn 0x3315fe88 "[email protected]"] 
startingclojure.core=> 

startingclojure.core=> (printlmt "test") 

IllegalArgumentException No method in multimethod 'printlmt' for dispatch value: 4 clojure.lang.MultiFn.getFn (MultiFn.java:156) 
startingclojure.core=> 
+0

我的代码适用于我 – Lee

+0

@Lee我添加了实际的控制台文本。你能否看看是否有什么问题。 – Teddy

+2

这两个代码都没有问题。你有没有试过退出然后重新启动repl?愚蠢的问题,但也许是一个旧的printlmt错误定义仍然在这里 –

回答

2

如果你不想重新启动用于重新定义方法REPL,使用remove-method

https://clojuredocs.org/clojure.core/remove-method

(remove-method printlmt true) 

然后重新定义。

编辑
您可以使用

(ns-unmap *ns* 'printlmt) 

注:ns-unmap将需要重新定义所有的方法为好。

+0

谢谢!这工作,并且(remove-all-methods multifn)。这仍然不能帮助我重新定义defmulti dispatch函数。我尝试使用不同的功能重新尝试defmulti,但仍旧以旧的方式工作。例如,在我的情况下,我将开关长度从10更改为5.仍然将“真”方法称为长度10. – Teddy

+0

@Teddy查看我的编辑。 –

+0

谢谢! ns-unmap工作!但是,可能这是一个不同的问题,我找不到如何在defmulti中列出所有def方法。这些方法不会显示在名称空间上调用dir。并且在多方法名称上调用源也没有帮助。 – Teddy