2011-07-08 46 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

是的,这是完全正确的:)

,如果你希望别人想在以后扩展您的协议这种情况的主要原因是。