2016-09-30 91 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