2013-03-28 28 views
14

通常,當我在庫中看到clojure協議時,協議方法將被包裝在一個函數中,通常很少添加功能。例如:爲什麼clojure協議方法經常被函數包裝?

(defprotocol Pfoo 
    (foo-method [this])) 

(deftype Atype [x y] 
    Pfoo 
    (foo-method [this] (do-something))) 

(defn foo [arg] (foo-method arg)) 

而且客戶端通常需要調用函數foo,而不是協議中的foo-method。 (請參閱clojurescript core頂部的協議以瞭解此類事物的具體示例。

那麼爲什麼協議經常被掩蓋在函數後面?難道協議方法不能成爲面向客戶端的部分,而不是包裝函數?

回答

22

協議代表的接口點兩種混凝土實體之間,一個是調用協議(任何在您的示例調用foo)的代碼,另一種是在代碼執行它(Atypefoo-method)什麼是方便一個可能對另一方來說不方便,實現者希望提供完整的最小接口,而呼叫者需要可以支持的最豐富的API。

你提到過ClojureScript核心;看看那裏的ISeq協議。它由幾種類型實現,每種類型必須實現-first-rest。爲了使這些儘可能簡單到實現,無需在其arg上調用seq。但是,面向調用者的相關函數firstrest支持傳入非seqs,如字符串,向量等,因此這種通用功能由非協議函數提供。當然,面向調用者的API甚至比next,map,filter,順序解構等均建立在-first-rest之上。

包裝協議方法的fns提供的其他常見功能包括參數驗證(如斷言),默認參數和對var-args的支持。

+0

另請參閱http://www.gotw.ca/publications/mill18.htm – Chouser 2013-05-13 13:27:55