【发布时间】:2020-09-16 15:33:15
【问题描述】:
我目前正在以相同的协议作为基础实现多种类型,并希望减少为了使用它们而需要包含在命名空间中的文件数量。举个例子:
basetype.clj
(defprotocol Base
(do-something [obj]))
(deftype Basetype [obj]
...
Base
(do-something [obj] something-something))
second_type.clj
(ns project.second-type
(:use project.basetype))
(deftype DifferentType [obj]
...
Base
(do-something [obj] something-slightly-different))
我所做的是为Basetype 构建的所有内容也适用于DifferentType。但是,我想通过在命名空间中包含 second_type.clj 而不是同时包含两者来访问函数 do-something。有没有办法做到这一点?
【问题讨论】:
-
您可以执行以下操作以从
second_type重新导出do-something:在 seond_type.clj 的末尾您是(ns-unmap 'project.second-type 'do-something),然后是(intern 'project.second-type 'do-something a/do-something)。然后这个 do-something 将被转入另一个需要第二种类型的命名空间 -
Clojure 甚至对实现继承的出现表示遗憾:消费者对协议进行操作,对具体类型不感兴趣。它们需要 basetype 并调用 defprotocol 在 basetype ns 中创建的普通函数。还有另一种理论,那都是无稽之谈。调用者应使用 Java 互操作点表示法 (.methodName obj),因此它们不需要基本类型 ns。但这是有风险的——你已经放弃了面向对象的 FP,并且失去了用你自己的 fns 包装 defprotocol 创建的 fns 的机会,这些 fns 可以进行更多的日志记录或类型检查。
标签: clojure namespaces protocols