【发布时间】:2011-06-02 06:56:15
【问题描述】:
我在 clojure 程序中使用了许多映射和结构。将这些转换为 defrecord 有什么好处(除了性能)?
【问题讨论】:
标签: clojure
我在 clojure 程序中使用了许多映射和结构。将这些转换为 defrecord 有什么好处(除了性能)?
【问题讨论】:
标签: clojure
我认为结构已被有效弃用,因此我根本不使用它们。
当我在许多地图实例中使用一组固定的已知键时,我通常会创建一条记录。最大的好处是:
记录的一些缺点:
【讨论】:
defstruct。见lispworks.com/documentation/HyperSpec/Body/…。
Stuart Sierra 最近写了一篇关于“使用 Clojure 1.2 解决表达式问题”的有趣文章,其中还包含一个关于 defrecord 的部分:
http://www.ibm.com/developerworks/java/library/j-clojure-protocols/index.html#datatypes
我认为整篇文章是理解协议和记录的一个很好的起点。
【讨论】:
另一个主要好处是记录有一个类型(它的类),您可以发送出去。
使用此功能但不代表所有可能用途的示例如下:
(defprotocol communicate
(verbalize [this]))
(defrecord Cat [hunger-level]
communicate
(verbalize [this]
(apply str (interpose " " (repeat hunger-level "meow")))))
(defrecord Dog [mood]
communicate
(verbalize [this]
(case mood
:happy "woof"
"arf")))
(verbalize (->Cat 3))
; => "meow meow meow"
(verbalize (->Dog :happy))
; => "woof"
【讨论】:
在大多数情况下使用映射,仅在需要多态性时使用记录。仅使用地图,您仍然可以使用多种方法;但是,如果您需要协议,则需要记录。鉴于此,等到您需要协议后再诉诸记录。在此之前,请避免使用它们,转而使用更以数据为中心且更简单的代码。
【讨论】:
除了前面提到的之外,除了在性能方面通常达到或优于标准外,并且在将相同的编程接口暴露为映射时,记录强制执行温和的结构:键名和键数强制执行为定义的时间。这可能有助于避免愚蠢的错误,即许多值都需要相同的结构(或者只是人为的刚性)。
无论最初的动机是什么,这个属性也将它与地图区分开来。
【讨论】: