当我在Clojure中遇到这个错误时,发生了什么?
java.lang.RuntimeException: No reader function for tag db/id
java.lang.RuntimeException: No reader function for tag db/id
这个错误信息与 Clojure 1.7 引入的一个特性 标签字面量 相关。标签字面量是一种简单的扩展方式, 可以将更多的数据类型表示为 Clojure 代码或 EDN 数据中的字面量。
Clojure 自带两个标签字面量的读取器,#inst
和 #uuid
,分别允许用字面量表示 java.util.Date
和
java.util.UUID
。可以通过在类路径上包含 data_readers.clj
文件来添加对更多标签的支持,
具体请参见文档。
导致这个错误的一些常见原因:
#db/id
字面量的 Datomic 事务数据:readers
*data-readers*
使用 EDN reader 的 Boot 任务 中。导致这个错误的一个常见原因是尝试在未传递 :readers
选项的情况下使用 EDN reader。来自
clojure.edn/read
的 doc string:
:readers - a map of tag symbols to data-reader functions to be
considered before default-data-readers. When not
supplied, only the default-data-readers will be used.
如其名,default-data-readers
只是 Clojure 自带的数据读取器映射表。也就是说,它不包含你使用的任何库的 data_readers.clj
文件中定义的读取器(比如说 Datomic)。在这种情况下,解决方案是传递当前加载的数据读取器集合,可以在变量 *data-readers*
中找到。
(clojure.edn/read {:readers *data-readers*} <your-read-source>)
或者更好的做法是,明确指定您想要使用的数据读取器的映射关系。例如,如果您只想使用Datomic数据读取器:
(require 'datomic.db
'datomic.function
'datomic.codec)
(edn/read {:readers {'db/id datomic.db/id-literal
'db/fn datomic.function/construct
'base64 datomic.codec/base-64-literal}}
<your-read-source-here>)
当然,由于这些只是Clojure地图,因此我们还可以通过合并地图来包括default-data-readers
:
(require 'datomic.db
'datomic.function
'datomic.codec)
(edn/read {:readers (merge
default-data-readers
{'db/id datomic.db/id-literal
'db/fn datomic.function/construct
'base64 datomic.codec/base-64-literal})}
<your-read-source-here>)