我在我的 Clojure 程序中使用了许多映射和结构。将这些数据转换为解除记录有什么好处(除了性能之外) ?
另一个主要的好处是记录有一个类型(它的类) ,您可以分派出去。
下面的例子使用了这一特性,但并不能代表所有可能的用途:
(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"
我认为结构被有效地弃用了,所以我根本不使用它们。
当我在许多映射实例中使用一组固定的已知键时,我通常会创建一条记录。最大的好处是:
记录的一些缺点:
Stuart Sierra 最近写了一篇关于“用 Clojure 1.2解决表达式问题”的有趣文章,其中也包含了关于 defrecord的部分:
defrecord
Https://web.archive.org/web/20110821210021/http://www.ibm.com/developerworks/java/library/j-clojure-protocols/#datatypes
我认为整篇文章是理解协议和记录的一个很好的起点。
在大多数情况下使用映射,只有在需要多态性时才使用记录。单独使用映射仍然可以使用多方法; 但是,如果需要协议,则需要记录。考虑到这一点,等到需要协议的时候再求助于记录。在此之前,请避免使用它们,而选择更以数据为中心、更简单的代码。
除了前面提到的,除了在性能方面通常达到或超过标准,以及在显示与 map 相同的编程接口时,记录强制执行温和的结构: 在定义时强制执行键名和键数。这可能有助于避免出现愚蠢的错误,因为这些错误需要从多个值中得到相同的结构(或者只是人为地严格执行)。
无论最初的动机是什么,这个属性也使它有别于地图。