2011-07-08 68 views
6

據我所知,如果我想定義一個只能由一個defrecord實現的協議(defprotocol),我仍然必須先定義協議,然後定義實現它的defrecord將Clojure defprotocol和defrecord結合

(defprotocol AProtocol 
    (a-method [this]) 
    (b-method [this that])) 

(defrecord ARecord [a-field b-field] 
    AProtocol 
    (a-method [this] ...) 
    (b-method [this that] ...)) 

有沒有辦法將兩者結合起來,或許與「匿名」協議結合?

+1

有你不想使用普通功能的原因是什麼? – Jonas

+0

@Jonas:我可能要在協議重構的'後來defprotocol'讓別人記錄可以實現它,但是在目前的時間,我不知道。我想我可以隨時將普通函數改爲協議函數,作爲重構的一部分。我也不能在不實現協議的情況下「覆蓋」像'count'這樣的內置函數,否則我會影響默認綁定。 – Ralph

+1

名爲'count'的協議函數也會影響內置。 – amalloy

回答

11

不要這樣做。你的記錄實現的「私人」或「匿名」協議只是用具有更好選擇的語言重新發明了無意義的OOP版本。定義一個在您的記錄上運行的常規舊功能;沒有理由必須對它們進行物理依賴。

如果以後要重構它是不是一個協議......這很容易!客戶端將無法區分,因爲協議函數調用看起來就像常規函數調用一樣。

+0

如果新功能與現有「核心」功能相同,會發生什麼情況?它不會影響核心功能嗎? – Ralph

+0

在這種情況下,您將不得不使用名稱空間來限定它。我的/ + vs + –

+0

@Ralph看到我對你的問題的評論。是的,它會影響核心功能,但使用協議也會。如果你真的希望它是匿名的,你可以附加函數作爲記錄的一個字段:'(defrecord Foo [count-me])...(let [x(Foo。(constant 1))] ... ((:計數我x)x))' – amalloy

4

是的,這是完全正確的:)

,如果你希望別人想在以後擴展您的協議這種情況的主要原因是。