使用defrecord与defprotocol的注意事项

Fri 22 July 2011
  • 手艺 tags:
  • clojure
  • programming published: true comments: true

简单地说,protocol是clojure中的接口,record是clojure中的数据类型。

可以通过这样的code定义一个protocol
[cc lang="clojure"]
(defprotoco DummyProtocol
"doc string..."
(method-one [self x] "doc string..."))
[/cc]

需要注意的是,protocol里所有方法的第一个参数都是self/this参数(类似python),从第二个开始才是调用时传入的参数。如果方法要重载呢?

[cc lang="clojure"]
(defprotocol DummyProtocol
"doc string..."
(method-one [self x] [self x y] "doc string")
) [/cc]

Apress的 Practical Clojure 书里的例子,给重载的参数表加上了括号,这样会导致编译错误(注记)。

定义一个record实现protocol

[cc lang="clojure"]
(defrecord DummyRecord [a b c]
DummyProtocol
(method-one [self x] (+ a x))
(method-one [self x y] (+ a x y)))
[/cc]
Practical Clojure里关于这部分的代码,又丢掉了self参数(注记)。

最后还有一个问题,如果直接use你的ns,你会发现调用record时出现:
java.lang.IllegalArgumentException: Unable to resolve classname: DummyRecord

怎么回事,不是都use了吗?原因是record被编译成了java对象,所以引用时要用java对象的引用方式,import之。