2016-12-16 43 views
2

試圖從字符串中讀取哈希映射,但如果鍵是「關鍵字」類型的值我從cljs.reader/read-string中得到錯誤。從字符串中讀取哈希映射的正確方法是什麼?Clojurescript如何使用數字關鍵字讀取字符串映射?

這個版本不包含關鍵字的工作:

(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"} 
+0

如果這些關鍵字是在某些API調用之間生成的,則只需在您的結尾禁用關鍵字轉換即可。數字可以生成很好的鍵如果這是第一個有「奇怪」行爲的地方,其他人會跟隨。 '(關鍵字s)'接受任何東西,你最終可能會破碎的東西。嘗試'(pr-str {(關鍵字「a:b」):c})' – cfrick

回答

5

cljs.reader不支持以數字字符開頭的關鍵字,可能是因爲符號和外延nsion,關鍵字必須以非數字字符開頭,儘管官方文檔中的公式可用於多種解釋。請參閱http://clojure.org/reference/reader#_symbolshttp://clojure.org/reference/reader#_literals

clojure reader(jvm實現)始終支持關鍵字:1234,現在可能不會改變。失敗的

較短例如:

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

附錄:它一直可以使用「未定義行爲」下的keyword功能和使用這些關鍵字產生的問題降到建造新的不可讀關鍵字Clojure中 - 中換句話說:你對你自己,如果你不喜歡的東西(keyword " ")

附錄1:JIRA票關於cljs.reader問題是http://dev.clojure.org/jira/browse/CLJS-677

+0

因此,從我所瞭解的clojure閱讀器意外地支持以數字字符開頭的關鍵字如:1234正確? – slhsen

+0

@slhsen我認爲是這樣,但數字關鍵字有點特殊;數字*符號*會與數字文字發生衝突,因此它們必須被禁止以防止歧義語法,但數字關鍵字可以工作(並且可以在clojure/jvm中工作)。你只是不能做的事情,如將數字關鍵字轉換爲符號(然後'讀取它) –

+0

似乎有一個在Clojurescript中的錯誤報告,一般共識是應該在Clojure第一方面解決:) http:///dev.clojure.org/jira/browse/CLJS-677 @Joost Diepenmaat你可以添加URL到你的答案? – slhsen

4

在Clojure方面,最初的意圖是關鍵字標識符遵循與符號標識符基本相同的規則(其中不允許前導數字)。

然而,用於接受這些的正則表達式是錯誤的(由於它是如何與符號一起使用的,然後是關鍵字和前導數字的區別)。尤其是,領先的:弄亂了它。該修補程序在CLJ-1252中實施,並在Clojure 1.6的工作期間承諾。

我們在發佈1.6版的早期版本後立即瞭解到,很多人實際上都在使用帶有前導數字的關鍵字。特別是,我記得java.jdbc以這種方式命名列。

由於在一切工作正常的情況下沒有任何好的理由可以打破這些程序,我們恢復了變化,並基本上賦予了關鍵字接受數字的能力。我不認爲這可能會在Clojure中發生變化。在這一點上,我認爲ClojureScript應該可以效仿並匹配Clojure。

edn是一種不同的故事 - 它在許多方面比Clojure/ClojureScript更有限制。在這一點上,待定將會在那裏完成。

+1

我可以理解爲什麼EDN比Clojure/ClojureScript更具限制性,但是目前狀態的東西我可以通過pr-str從Clojurescript輸出EDN,這就是您如何在Clojurescript afaik中執行此操作,用閱讀器/閱讀功能閱讀它很奇怪。 pr-str的源代碼並不聲稱輸出EDN,所以就是這樣。在這種情況下,可能是Clojurescript應該有一個專門的功能,只輸出有效的EDN(我似乎無法找到一個,如果有的話) – slhsen

+1

同意,如果有一個pr變體設計爲只發出edn-safe數據。 –