我有一个疯狂的想法,包括将一些 clojure 代码放入 CouchDB 并编写查询它的 View 。我不想将 clojure 代码存储为纯文本,因为那样我就不得不担心在 View 中解析它。格式和注释不需要保留,但代码应该能够在不改变结构的情况下进出数据库。关键字、符号和字符串都应保持其 native 类型。此外,我希望代码看起来优雅且高效。
我正在考虑将事物表示如下:
- 以 ' 开头的字符串形式的符号
- 以 : 开头的字符串形式的关键字
- 未经修改的字符串,除非它们以 ' 或 : 开头,在这种情况下,它们会使用反斜杠进行转义。
- (括号)作为数组
- [brackets] 以“_[]”为第一个元素的数组
- 将 ({}) 映射为对象
- 将 (#{}) 设置为值设置为 1 并包含“_#{}”的对象。
我们对批评、经验和想法表示赞赏。
编辑:如果我尝试使用 clojure.contrib 中的 json 函数读写 JSON 代码,会发生以下情况:
user> code
((ns bz.json.app (:use (ring.middleware file))) (defn hello [req] {:status 200, :headers {"Content-Type" "text/plain"}, :body "Hello World!"}) (def app (wrap-file hello "public")))
user> (read-json (json-str code))
[["ns" "bz.json.app" ["use" ["ring.middleware" "file"]]] ["defn" "hello" ["req"] {"body" "Hello World!", "headers" {"Content-Type" "text/plain"}, "status" 200}] ["def" "app" ["wrap-file" "hello" "public"]]]
为了使上面的第 4 行与第 2 行完全一样,需要做一些事情。看起来它是一个库项目,除非在某个地方有一个我不知道的函数可以做到这一点。
有了这样一个库,它的名称可能如下所示:
user> (= (json-to-code (read-json (json-str (code-to-json code)))) code)
true
最佳答案
正如 mikera 建议的那样,clojure.contrib.json/write-json 不仅会转换原始类型,还会转换 Clojure 的 ISeq
s 和 Java 的 Map
s、Collection
s 和 Array
s,也是。这应该涵盖了您的大部分代码(视为数据),但是如果您想编写任何更花哨的东西,可以通过模仿 Stuart Sierra 的源代码来轻松扩展 JSON 编写器(参见 here):
(defn- write-json-fancy-type [x #^PrintWriter out]
(write-json-string (str x) out)) ;; or something useful here!
(extend your-namespace.FancyType clojure.contrib.json/Write-JSON
{:write-json write-json-fancy-type})
这是假设您不需要存储计算的字节码或捕获的闭包。这将是一场完全不同的比赛,难度要大得多。但是由于大多数 Clojure 代码(像大多数 Lisp 一样)可以被视为 S-Expressions 的树/森林。 ,你应该没事的。
可以使用 clojure.contrib.json/read-json
将 JSON 解析回数据(花一点时间查看其定义中的选项,您可能想要使用它们)。在那之后,eval
可能是你最好的 friend 。
关于json - 如何将clojure代码映射到JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3436216/