为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)构造函数,这是构造新记录的首选方法。当使用这些函数时,不需要导入底层记录类,只需引用构造函数本身。你是对的,我只是用了错误的方法。这太完美了。谢谢