Clojure 运行时异常 - 没有 db/id 标签的读取器函数。

7
当我在Clojure中遇到这个错误时,发生了什么?
java.lang.RuntimeException: No reader function for tag db/id
1个回答

11

标签字面量

这个错误信息与 Clojure 1.7 引入的一个特性 标签字面量 相关。标签字面量是一种简单的扩展方式, 可以将更多的数据类型表示为 Clojure 代码或 EDN 数据中的字面量。

Clojure 自带两个标签字面量的读取器,#inst#uuid,分别允许用字面量表示 java.util.Datejava.util.UUID。可以通过在类路径上包含 data_readers.clj 文件来添加对更多标签的支持, 具体请参见文档

常见原因

导致这个错误的一些常见原因:

  • 尝试读取包含 #db/id 字面量的 Datomic 事务数据
  • 使用 EDN reader 时未传递 :readers
  • 在尝试通过传递 *data-readers* 使用 EDN reader 的 Boot 任务 中。

使用 EDN reader

导致这个错误的一个常见原因是尝试在未传递 :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>)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接