如何定义从现有类型“继承”协议的新记录?
为了明确这个问题,我将通过扩展Ubergraph进行说明,但Ubergraph只是一个例子;我正在寻找通用解决方案,而不仅仅是适用于Ubergraph的解决方案。假设我想向Ubergraph添加一个全局属性graph-name
。理想情况下,我可以这样做:
(defrecord named-ubergraph [g graph-name])
(extend-type named-ubergraph
(all-the-protocols-supported-by ubergraph.core.Ubergraph)
(call-the-same-functions-replacing-first-argument-with '(this g))
当然,我可以查看Ubergraph源代码并手动编写所有转发函数,但是as you can see here,Ubergraph满足许多协议和许多协议方法
编写如此多的样板代码听起来并不是非常简单,而且当我想要做的就是在Ubergraph上添加一个有趣的数据时,似乎需要做很多工作。什么是更好的方式?
如果您认为我看错了,请随意重新定义问题。
答案 0 :(得分:1)
extend-type
将现有类型扩展到给定的协议。
如果我理解正确,您希望扩展现有记录以实现某种继承。
AFAIK,没有简单的方法可以做到这一点。
但是,如果您只想添加其他字段,则可以轻松地assoc
现有记录实例的附加字段:
(defprotocol Cost
(cost [this price-list]))
(defrecord Car [name speed]
Cost
(cost [this price-list] (price-list (:name this))))
(def my-car (->Car "bmw" 200))
(def price-list {"bmw" 100000})
(cost my-car price-list)
;;=> 100000
(-> my-car
(assoc :color "blue")
(cost price-list))
;;=> 100000
更新: 我还在Clojure邮件列表上找到了这个精彩的讨论:与"继承":https://groups.google.com/forum/#!topic/clojure/mr-o9sRyiZ0
的defrecord