我试着按照文档进行操作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.`
以下结果出乎意料:
(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))))
Run Code Online (Sandbox Code Playgroud)
我该如何使用*data-readers*绑定?Clojure版本1.5.1.
Mic*_*zyk 11
clojure.edn默认情况下,函数只使用存储的数据读取器clojure.core/default-data-readers,从Clojure 1.5.1开始,它为读者提供即时和UUID文字.如果你想使用自定义阅读器,你可以通过传递一个:readers选项来做到这一点; 特别是,你可以传入*data-readers*.这在docstring中记录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*} "...")
Run Code Online (Sandbox Code Playgroud)
(以下部分是为了回应RichardMöhn在这个GitHub问题的评论帖中所做的评论.当前的问题是读者函数是否适合调用eval传入的数据.我不关心该项目有问题;请参阅机票了解详情,以及理查德对目前答案的评论.)
值得补充的*data-readers*是data_readers.{clj,cljc},Clojure在启动时在类路径的根目录中找到的任何文件都是隐式填充的.这可能很方便(它允许在Clojure源代码和REPL中使用自定义标记文字),但它确实意味着新数据读取器可能会出现在那里,并且单个依赖项发生了更改.使用显式构造的读取器映射clojure.edn是一种避免意外的简单方法(在处理不受信任的输入时可能特别讨厌).
(请注意,隐式加载过程不会导致任何代码被立即加载,或者甚至在*data-readers*首次遇到提到的标记时;填充的进程*data-readers*会创建具有未绑定Vars作为占位符的空命名空间,并实际使用那些仍然具有的读取器到require用户代码中的相关命名空间.)
该*data-readers*动态无功似乎适用于read-string并read从功能clojure.core而已.
(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 will read a java.util.Date
(->> instant read-string class println)
;; This will read a java.sql.Timestamp
(binding [*data-readers* reader-map]
(->> instant read-string class println)))
Run Code Online (Sandbox Code Playgroud)
在这里浏览clojure.edn阅读器的源代码,我找不到任何表明在那里使用相同var的东西.*data-readers*
clojure.core的功能read和read-string用途LispReader(使用的值来自*data-readers*),而功能则来自clojure.edn使用EdnReader.
这个edn库在Clojure中相对较新,因此可能是文档字符串edn对于core读者而言不够具体的原因,这可能会导致这种混淆.
希望能帮助到你.
| 归档时间: |
|
| 查看次数: |
2601 次 |
| 最近记录: |