gpt4 book ai didi

Clojure:在不定义新协议(protocol)的情况下向 defrecord 添加函数

转载 作者:行者123 更新时间:2023-12-03 12:09:05 26 4
gpt4 key购买 nike

我习惯于在 python/java 中使用 OO。现在做 Clojure。我遇到了 defrecord,但似乎我必须为我希望记录实现的每个函数或一组函数定义一个协议(protocol)。创建新协议(protocol)会产生摩擦。我不仅要命名我想要的功能,还要命名协议(protocol)。我正在寻找一种“很好地”将函数与记录关联的方法,以便函数可以通过 this 参数访问记录的参数,而无需定义新协议(protocol)或将函数添加到现有协议(protocol)。

最佳答案

如果您还没有尝试过multimethods然而,它们可能更接近您正在寻找的东西。

定义:

(defrecord Person [first middle last])
(defmulti get-name class)
(defmethod get-name Person [person] (:first person))

采用:
(def captain (Person. "James" "T" "Kirk"))
(get-name captain)

选择的多方法实现基于 defmulti 中的调度函数(一个函数,它接受传递给函数的 args 并返回一个调度值)。很常见的“类”是分派(dispatch)函数,就像这里一样,按类型分派(dispatch)。多方法支持多个独立的 ad-hoc 或基于 Java 的类型层次结构、默认实现等。

但总的来说,我认为您可能想退后一步,考虑您是否真的需要协议(protocol)或多方法。您似乎正在尝试在 Clojure 中“做 OO”。虽然 OO 的各个方面(如多态性)很棒,但也许您应该尝试以其他方式思考您的问题。例如,在我刚刚给出的示例中,没有令人信服的理由(还)以多态方式实现 get-name。为什么不直接说:
(defn get-name [x] (:first x))

你甚至需要一个人记录吗?一张简单的 map 就足够了吗?有时答案是肯定的,有时不是。

通常 Clojure 不提供类继承。如果你真的想要它,你当然可以构建一个等价物(即使使用协议(protocol)),但通常我发现在 Clojure 中还有其他更好的方法来解决这个问题。

关于Clojure:在不定义新协议(protocol)的情况下向 defrecord 添加函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5024211/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com