Clojure - 在 map 上使用记录有什么好处

标签 clojure functional-programming diamond-problem

我很难决定何时使用 defrecord如果我在我的记录中使用的协议(protocol)是语义 clojure 和功能性的,那么它是正确的选择,并且更广泛地说。
在我目前的项目中,我正在构建一个游戏,它具有不同类型的敌人,它们都具有相同的一组 Action ,而这些 Action 可能会以不同的方式实现。
来自 OOP 背景,我很想做类似的事情:

(defprotocol Enemy
  "Defines base function of an Enemy"
  (attack [this] "attack function"))

(extend-protocol Enemy
  Orc
  (attack [_] "Handles an orc attack")  
  Troll
  (attack [_] "Handles a Troll attack"))



(defrecord Orc [health attackPower defense])
(defrecord Troll [health attackPower defense])

(def enemy (Orc. 1 20 3))
(def enemy2 (Troll. 1 20 3))

(println (attack enemy))
; handles an orc attack

(println (attack enemy2))
;handles a troll attack

从表面上看,这似乎是有道理的。我希望每个敌人总是有一个攻击方法,但实际的实现应该能够根据特定的敌人而有所不同。使用 extend-protocol我能够创建对我的敌人不同的方法的有效调度,并且我可以轻松地添加新的敌人类型以及更改这些类型的功能。
我遇到的问题是为什么我应该在通用 map 上使用记录?以上对我来说有点 OOP 的感觉,并且似乎我正在反对一种更实用的风格。所以,我的问题分为两个:
  • 我上面的记录和协议(protocol)实现是一个合理的用例吗?
  • 更一般地说,什么时候记录比 map 更受欢迎?我已经读过,当您多次重新构建同一张 map 时,您应该支持记录(就像我在这种情况下一样)。这个逻辑合理吗?
  • 最佳答案

    九年后,这个流程图仍然是个好建议:https://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/ -- 似乎已移至 https://cemerick.com/blog/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form.html
    我的经验法则是:始终使用普通的哈希映射,直到你真的需要多态性,然后决定你是想要多方法(对一个或多个参数/属性进行调度)还是协议(protocol)(仅对类型进行调度)。

    关于Clojure - 在 map 上使用记录有什么好处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62684264/

    相关文章:

    clojure - 为什么 Leiningen 会陷入顶层空洞的 future ?

    clojure - 如何结束/强制关闭程序(在Clojure中)

    javascript - 如何在 JavaScript 中将 OOP 转换为 FP

    haskell - 让 putStrLn 在 if-else block 内工作

    C++/菱形继承(钻石问题)/静态变量

    clojure - 帮助我使这个 noob 代码更加地道

    recursion - 在功能上按空格分割字符串,按引号分组!

    java - 使用嵌套上限通配符时的不兼容类型

    c++ - 与第三方库的菱形继承(钻石问题)

    c++ - 虚拟派生的多态类的大小