2011-09-03 65 views

回答

4

這是不正確的,你正在檢查對象x是否實現IDeref接口,這只是意味着你可以用@符號取消引用對象。你想要的是這樣的:

(instance? clojure.lang.Ref x) 

編輯:

(調整徵求意見)。

您可以按照您的建議進行操作,但這樣做的缺點是將其他用戶所做的擴展IDeref的對象分類爲引用類型。還要考慮到變量也具有引用類型的作用,但不使用IDeref接口。

這裏有兩個很好的選擇。你可以寫一個使用或語句的函數:

(def ref? [x] 
    (or (instance? clojure.lang.Ref x) 
     (instance? clojure.lang.Agent x) 
     ...)) 

或者你可以使用協議來定義一個新的謂詞。這具有可擴展的優點。

(defprotocol Ireference? (reference? [this])) 

(extend-type java.lang.Object Ireference? (reference? [this] false)) 
(extend-type nil Ireference (reference? [this] false)) 
(extend-type clojure.lang.Ref Ireference? (reference? [this] true)) 
(extend-type clojure.lang.Agent Ireference? (reference? [this] true)) 

;;user=> (reference? nil) 
;;false 
;;user=> (reference? (ref 0)) 
;;true 

另一個例子看http://dosync.posterous.com/51626638

+1

我還會更進一步,使它成爲一個新的謂詞,如'(defn ref?[x](instance?clojure.lang.Ref x))' – skuro

+0

bmillare:我實際上詢問所有「引用」,而不僅僅是「ref 「和afaik,術語」參考「包括參考,原子和代理。 –

+0

還要注意的是,你不能用這樣的類文字用例:'(case(class「hi」)String true false) - > false' –

相關問題