为Clojure协议提供多个实现
我有一个公开公共数据相关函数的命名空间(为Clojure协议提供多个实现,clojure,Clojure,我有一个公开公共数据相关函数的命名空间(get images,insert user)。然后我有两个数据库后端,它们具有相同的功能,并以不同的方式实现它们。他们实现了原来的接口。每个后端都包含在一个命名空间中 我似乎无法找到一个很好的解决方案来实现这一点 我尝试动态加载ns,但没有成功。一旦执行(:require[abc:as x]),则x不是实际值 我试着使用defprotocol和deftype,但这很奇怪,因为deftype中的函数也需要导入,这对我来说把一切都搞砸了 有什么惯用的解决方法
get images
,insert user
)。然后我有两个数据库后端,它们具有相同的功能,并以不同的方式实现它们。他们实现了原来的接口。每个后端都包含在一个命名空间中
我似乎无法找到一个很好的解决方案来实现这一点
我尝试动态加载ns
,但没有成功。一旦执行(:require[abc:as x])
,则x
不是实际值
我试着使用defprotocol
和deftype
,但这很奇怪,因为deftype
中的函数也需要导入,这对我来说把一切都搞砸了
有什么惯用的解决方法吗?我不明白为什么协议是不够的 在ns data.api中:
(ns data.api)
(defprotocol DB
(get-images [this])
(insert-user [this]))
在ns data.1中:
(ns data.impl1
(:require [data.api :refer :all]))
(defrecord Database1 [connection-params]
DB
(get-images [_] ...)
(insert-user [_] ...))
在ns data.impl2中也是如此
然后,在使用特定数据库时,只需创建正确的记录:
(ns data.user
(:require [data.api :refer :all])
[data.impl1 :refer (->Database1)])
(defn use-db []
(let [db1 (->Database1 {})]
(get-images db1)))
FWIW,似乎使用另一个名称空间中的记录/类型的首选方法是
导入它们,即(:导入[data.impl1 Database1])
在(ns data.user…
@DaveYarwood:是吗?那条线索对我来说并不是那么回事。只有一个人这样做,他想知道为什么这种方法需要下划线而不是破折号。这个线程可能早于Clojure 1.4。从1.4开始,defrecord会创建位置(例如->数据库1)和地图(例如地图->数据库1)构造函数,这是构造新记录的首选方法。当使用这些函数时,不需要导入底层记录类,只需引用构造函数本身。你是对的,我只是用了错误的方法。这太完美了。谢谢