跨多个名称空间使用 clojure 协议

Using clojure protocol across multiple namespaces

我目前正在使用相同的协议实现多种类型作为基础,并希望减少为了使用它们而需要包含在名称空间中的文件数量。举个例子:

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 。有办法实现吗?

正如我在评论中提到的,您应该能够从任何命名空间重新导出任何值。

你可以像这样构造简单的函数:

(defn reexport [from-ns name]
  (ns-unmap *ns* name)
  (intern *ns* name @(ns-resolve from-ns name)))

(reexport 'project.basetype 'do-something)

或重新导出给定 ns 中的所有值:

(defn reexport-all [from-ns]
  (run! (partial reexport from-ns) (map first (ns-publics from-ns))))

(reexport-all 'project.basetype)

回复:

user> (ns x)
nil

x> (defn f [v] (inc v))
#'x/f

x> (ns y)
nil

y> (user/reexport 'x 'f)
#'y/f

y> (in-ns 'user)
#namespace[user]

user> (y/f 10)
11

user> (in-ns 'y)
#namespace[y]

y> (defn f2 [v] (dec v))
#'y/f2

y> (ns z)
nil

z> (user/reexport-all 'y)
nil

z> (in-ns 'user)
#namespace[user]

user> (z/f 1)
2

user> (z/f2 1)
0