为什么在记录中实现功能?

时间:2014-08-16 17:23:54

标签: clojure record

可以在记录中实现协议(以及相关的类型)。但是,如果这些特定函数只实现一次(即仅针对一种记录类型)或者所有记录都使用该特定函数的相同实现,我想知道是否有任何理由这样做。

为了说明,说我有播放器的记录。

(defrecord Player [x y hp inventory])

现在我有机会实施更新协议;

(defprotocol Update
  (update [this world]))

(defrecord Player [x y hp inventory]
  Update
  (update [this world] this))

或者,我可以为此写一个单独的函数。

(defn update [player world] player)

这两者之间有什么区别,效率还是真的?

2 个答案:

答案 0 :(得分:2)

  • update的简单函数定义不会进行类型检查以确保您只是将Players传递给它,但定义的协议版本会执行,并将抛出{ {1}}。你可能想要这种类型的安全性。或者您可能只想与他人沟通期望的论点,但还有其他方法可以做到这一点。

  • 协议版本更加冗长,增加了可能无用的复杂性。您可能希望简单的函数定义简单。

我认为在Clojure世界中,当它们之间存在权衡时,更喜欢简单表达而不是类型安全,但这取决于项目和程序员。就个人而言,我通常想要更简单的代码,但在某些情况下我会倾向于另一个方向。

还有一些明显的考虑因素:

  • 协议版本可能会让人感到困惑,因为协议通常用于允许多态行为,因此他们希望为多种记录类型定义协议。

  • 如果您希望将来需要多态,您可能希望通过使用协议从头开始设置代码。

最后:

  • 我没有关于效率的答案。其他人可能对此有所帮助。但是,您可以使用Criterium运行测试,以查看代码是否存在差异。

答案 1 :(得分:1)

这应该是对Mars回答的评论。

关于效率...... 根据“Clojure的喜悦”第2版。 (好奇的第216页),使用内联定义协议方法调用方法比通过扩展实现协议的对象调用方法快几倍。