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