2012-09-22 6 views
5

を実装する際のClojureを使用するSayHiのどの実装を決定しない方法のClojureでセット、マップやベクトルIPersistentCollectionとIFNの両方を実装して、与えられた:決議は、クラスは複数のインターフェイス

(defprotocol SayHi 
    (hi [this])) 

(extend-protocol SayHi 
    clojure.lang.IPersistentCollection 
    (hi [_] (println "Hi from collection")) 
    clojure.lang.IFn 
    (hi [_] (println "Hi from Fn!")) 
    clojure.lang.IPersistentSet 
    (hi [_] (println "Hi from set!"))) 

(hi #{}) 
Hi from set! 
(hi []) 
Hi from collection 

答えて

5

議定ディスパッチが行われますが関数の第1引数の型について説明します。複数の実装が最初の引数の型と一致する場合、最も具体的な実装が選択されます。そのため、セット(#{})が両方とも実装されていても、(hi #{})コールはset実装に解決され、collectionまたはfn実装には解決されません。

clojure-deftype.cljfind-protocol-impl関数は、オブジェクトの解像度を実装するプロトコルを処理するようだ:

(defn find-protocol-impl [protocol x] 
    (if (instance? (:on-interface protocol) x) 
    x 
    (let [c (class x) 
      impl #(get (:impls protocol) %)] 
     (or (impl c) 
      (and c (or (first (remove nil? (map impl (butlast (super-chain c))))) 
        (when-let [t (reduce1 pref (filter impl (disj (supers c) Object)))] 
         (impl t)) 
        (impl Object))))))) 
+1

あなたはこれが行われているClojureのソースコードを指すことはできますか?私はそれを見つけることができませんでした – DanLebrero

+1

@ dAniは答えを更新 –

関連する問題