我尝试按照 clojure.instant/read-instant-timestamp
的文档进行操作,内容如下:
clojure.instant/read-instant-timestamp To read an instant as a java.sql.Timestamp, bind *data-readers* to a map with this var as the value for the 'inst key. Timestamp preserves fractional seconds with nanosecond precision. The timezone offset will be used to convert into UTC.`
The following result was unexpected:
(do
(require '[clojure.edn :as edn])
(require '[clojure.instant :refer [read-instant-timestamp]])
(let [instant "#inst \"1970-01-01T00:00:09.999-00:00\""
reader-map {'inst #'read-instant-timestamp}]
;; This binding is not appearing to do anything.
(binding [*data-readers* reader-map]
;; prints java.util.Date -- unexpected
(->> instant edn/read-string class println)
;; prints java.sql.Timestamp -- as desired
(->> instant (edn/read-string {:readers reader-map}) class println))))
如何使用
*data-readers*
捆绑? Clojure 版本 1.5.1。
最佳答案
clojure.edn
默认情况下,函数仅使用存储在 clojure.core/default-data-readers
中的数据读取器从 Clojure 1.5.1 开始,它为读者提供即时和 UUID 文字。如果你想使用自定义阅读器,你可以通过传入 :readers
来实现。选项;特别是,您可以传入 *data-readers*
.这记录在 clojure.edn/read
的文档字符串中。 (clojure.edn/read-string
的文档字符串是指 read
的文档字符串)。
这里有些例子:
(require '[clojure.edn :as edn])
;; instant literals work out of the box:
(edn/read-string "#inst \"2013-06-08T01:00:00Z\"")
;= #inst "2013-06-08T01:00:00.000-00:00"
;; custom literals can be passed in in the opts map:
(edn/read-string {:readers {'foo identity}} "#foo :asdf")
;= :asdf
;; use current binding of *data-readers*
(edn/read-string {:readers *data-readers*} "...")
(以下部分是为了响应 Richard Möhn 在 this GitHub issue 的评论线程中所做的评论而添加的。直接的问题是阅读器函数是否适合对传入的数据调用
eval
。我不是与有问题的项目相关联;有关详细信息,请参阅票证,以及理查德对当前答案的评论。)值得补充的是
*data-readers*
从任何 data_readers.{clj,cljc}
隐式填充Clojure 在启动时在类路径的根目录中找到的文件。这可能很方便(它允许在 Clojure 源代码和 REPL 中使用自定义标记文字),但这确实意味着新的数据读取器可能会出现在其中,并更改单个依赖项。使用带有 clojure.edn
的显式构造的阅读器映射是一种避免意外的简单方法(在处理不受信任的输入时可能会特别讨厌)。(请注意,隐式加载过程不会导致立即加载任何代码,甚至当第一次遇到
*data-readers*
中提到的标签时;填充 *data-readers*
的过程会创建空的命名空间,并将未绑定(bind)的 Vars 作为占位符,并实际上使用这些阅读器仍然需要 require
用户代码中的相关命名空间。)
关于clojure - 如何将 *data-readers* 与 edn 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16989337/