Clojurescript如何用数字关键字读取字符串映射?

时间:2016-12-16 08:10:03

标签: clojure clojurescript

尝试从字符串中读取哈希映射,但如果键是“关键字”类型值,则从cljs.reader / read-string收到错误。从字符串中读取哈希映射的正确方法是什么?

此版本不含关键字:

(cljs.reader/read-string (pr-str {1 "a", 1481876814936 "sdafa", 1481876816039 "afdas", 1481876817344 "asdfa", 2 "b"}))
=> {1 "a", 1481876814936 "sdafa", 1481876816039 "afdas", 1481876817344 "asdfa", 2 "b"}

但是这个带有关键字的版本会引发错误:

(cljs.reader/read-string (pr-str {:1 "a", :1481876814936 "sdafa", :1481876816039 "afdas", :1481876817344 "asdfa", :2 "b"}))
 cljs.user=> #object[TypeError TypeError: Cannot read property '0' of null]
TypeError: Cannot read property '0' of null
    at cljs$reader$read_keyword (file:///test/resources/public/js/ui-out/cljs/reader.js:681:19)
    at cljs$reader$read_delimited_list (file:///test/resources/public/js/ui-out/cljs/reader.js:397:20)
    at cljs$reader$read_map (file:///test/resources/public/js/ui-out/cljs/reader.js:466:41)
    at cljs$reader$read (file:///test/resources/public/js/ui-out/cljs/reader.js:879:34)
    at cljs$reader$read_string (file:///test/resources/public/js/ui-out/cljs/reader.js:911:25)
    at eval (eval at figwheel$client$utils$eval_helper (file:///test/resources/public/js/ui-out/figwheel/client/utils.js:143:8), <anonymous>:1:114)
    at eval (eval at figwheel$client$utils$eval_helper (file:///test/resources/public/js/ui-out/figwheel/client/utils.js:143:8), <anonymous>:9:3)
    at eval (eval at figwheel$client$utils$eval_helper (file:///test/resources/public/js/ui-out/figwheel/client/utils.js:143:8), <anonymous>:14:4)
    at figwheel$client$utils$eval_helper (file:///test/resources/public/js/ui-out/figwheel/client/utils.js:143:8)
nil

相同的代码适用于clojure:

user=> (read-string (pr-str {:1 "a", :1481876814936 "sdafa", :1481876816039 "afdas", :1481876817344 "asdfa", :2 "b"}))
{:1 "a", :1481876814936 "sdafa", :1481876816039 "afdas", :1481876817344 "asdfa", :2 "b"}

2 个答案:

答案 0 :(得分:5)

cljs.reader不支持以数字字符开头的关键字,可能是因为符号和扩展名关键字必须以非数字字符开头,尽管官方文档中的表述可以使用多种解释。请参阅http://clojure.org/reference/reader#_symbolshttp://clojure.org/reference/reader#_literals

clojure阅读器(jvm实现)总是支持像:1234这样的关键字,现在可能不会改变。

失败的较短例子:

(require 'cljs.reader)
(cljs.reader/read-string ":1")

附录:使用keyword函数在clojure中构建其他类型的不可读关键字总是可能的,并且使用这些关键字导致的问题属于&#34;未定义的行为&#34; - 换句话说:如果你做(keyword " ")

之类的事情,你就自己动手了

附录1:关于cljs.reader中问题的JIRA票证位于http://dev.clojure.org/jira/browse/CLJS-677

答案 1 :(得分:4)

在Clojure方面,最初的意图是关键字标识符遵循与符号标识符基本相同的规则(不允许使用前导数字)。

然而,用于接受这些的正则表达式是错误的(由于它如何与符号串联使用,然后是关键字和前导数字的差异)。特别是,领先的:会使其混乱。该修复程序在CLJ-1252中实现,并在Clojure 1.6工作期间提交。

我们在发布1.6的早期版本后立即了解到很多人实际上使用的是带有前导数字的关键字。特别是,我记得java.jdbc正在以这种方式命名列。

由于在一切正常的情况下似乎没有任何理由打破这些程序,我们还原了这一变化,并且基本上使关键字能够接受数字。我不认为这可能会在Clojure中发生变化。在这一点上,我认为ClojureScript可能会效仿并匹配Clojure。

edn是一个不同的故事 - 它有意在许多方面比Clojure / ClojureScript更具限制性。在这一点上,TBD会在那里完成。