7

当我在 Clojure 中收到此错误时会发生什么?

java.lang.RuntimeException: No reader function for tag db/id
4

1 回答 1

11

标记文字

此错误消息与 Clojure 1.7 中引入的一个特性有关,即 tagged literals标记文字是扩展在 Clojure 代码或EDN数据中可以表示为文字的数据类型的一种简单方法 。

Clojure 附带了两个标记文字的阅读器,#inst并 允许和 #uuid的文字表示。如文档中所述,可以通过在类路径中包含文件来添加对更多标签的支持 。java.util.Datejava.util.UUIDdata_readers.clj

常见原因

此错误的一些常见原因:

  • 尝试读取包含#db/id文字的 Datomic 事务数据
  • 尝试使用EDN 阅读器时不通过:readers
  • 在尝试通过传递来使用 EDN 阅读器的 引导*data-readers*任务中。

使用 EDN 阅读器

此错误的一个常见原因是尝试使用EDN 阅读器 而不传递该:readers选项。从文档字符串中 clojure.edn/read

: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)的文件中定义的任何阅读器。这种情况下的解决方案是传递当前加载的数据读取器集,在 var 中找到 *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>)
于 2017-08-23T01:31:12.297 回答