Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure&;ClojureScript:clojure.core/read-string、clojure.edn/read-string和cljs.reader/read-string_Clojure_Clojurescript_Edn - Fatal编程技术网

Clojure&;ClojureScript:clojure.core/read-string、clojure.edn/read-string和cljs.reader/read-string

Clojure&;ClojureScript:clojure.core/read-string、clojure.edn/read-string和cljs.reader/read-string,clojure,clojurescript,edn,Clojure,Clojurescript,Edn,我不清楚所有这些读取字符串函数之间的关系。很明显,clojure.core/read string可以读取由pr[n]甚至print dup输出的任何序列化字符串。同样清楚的是,clojure.edn/read string会读取根据 但是,我从Clojure脚本开始,不清楚cljs.reader/read string是否符合要求。这个问题是由以下事实引发的:我有一个web服务以这种方式序列化clojure代码: (with-out-str (binding [*print-dup* true

我不清楚所有这些读取字符串函数之间的关系。很明显,
clojure.core/read string
可以读取由
pr[n]
甚至
print dup
输出的任何序列化字符串。同样清楚的是,
clojure.edn/read string
会读取根据

但是,我从Clojure脚本开始,不清楚
cljs.reader/read string
是否符合要求。这个问题是由以下事实引发的:我有一个web服务以这种方式序列化clojure代码:

(with-out-str (binding [*print-dup* true] (prn tags)))
这将生成包含数据类型的对象序列化。但是,
cljs.reader/read string
无法读取此内容。我总是遇到这种类型的错误:

Could not find tag parser for = in ("inst" "uuid" "queue" "js")  Format should have been EDN (default)
起初,我以为这个错误是由
cljs ajax
引发的,但是在rhino REPL中测试
cljs.reader/read字符串之后,我得到了相同的错误,这意味着它是由
cljs.reader/read字符串本身引发的。它是由
cljs.reader
中的
maybe read taged type
函数抛出的,但不清楚这是因为读取器仅处理EDN数据,还是

此外,从文件中,唯一要说的是:

The read and read-string functions are located in the cljs.reader namespace

这表明它们应该具有完全相同的行为。

cljs.reader/read
仅支持EDN,但
pr
等将输出不会读取的标记(尤其是协议和记录)

通常,如果在Clojure端您可以验证
(=value(Clojure.edn/read-string(pr-str-value)))
,那么您的cljs互操作应该可以工作。这可能是有限的,并且有一些关于EDN库的解决方法或修复方法的讨论


根据数据的外观,您可以查看标记的
库,如。

摘要中所述:Clojure是EDN的超集。默认情况下,
pr
prn
pr str
在给定Clojure数据结构时,会生成有效的EDN
*print dup*
改变了这一点,使他们能够充分利用Clojure的强大功能,在往返之后对内存中对象的“相同性”提供更有力的保证。ClojureScript只能读取EDN,不能读取完整Clojure

简单的解决方案:不要将
*print dup*
设置为true,只将纯数据从Clojure传递到ClojureScript

更难的解决方案:使用带标签的文本,两边都有一个(可能是共享的)关联读取器。(不过,这仍然不涉及打印dup*
。)

切点相关:EDN的大多数用例都包含在中,速度更快,尤其是在ClojureScript方面


让我们从Clojure部分开始。Clojure从一开始就有一个
Clojure.core/read string
函数,它
read
s是一个旧的Lispy意义上的read-Eval-Print循环字符串,也就是说,它允许访问Clojure编译中使用的实际读取器。[0]

后来,Rich Hickey&co决定推广Clojure的数据表示法,并出版了。EDN是Clojure的一个子集;它仅限于Clojure语言的数据元素

由于Clojure是一种Lisp语言,并且像所有Lisp语言一样,宣扬“代码就是数据就是代码”的理念,因此上述段落的实际含义可能并不完全清楚。我不确定任何地方都有详细的差异,但仔细检查和前面提到的EDN规范会发现一些差异。最明显的区别在于宏字符,尤其是
#
分派符号,它在Clojure中的目标比在EDN中的目标多得多。例如,
#(*%%)
符号是有效的Clojure,Clojure读取器会将其转换为以下EDN的等价物:
(fn[x](*x))
。对于这个问题特别重要的是很少有文档记录的
#=
特殊读取器宏,它可以用来在读取器内部执行任意代码

由于Clojure阅读器可以使用完整的语言,因此可以将代码嵌入阅读器正在读取的字符串中,并在阅读器中对其进行评估。可以找到几个例子

clojure.edn/read string
函数严格限制为edn格式,而不是整个clojure语言。特别是,它的操作不受
*read eval*
变量的影响,并且无法读取所有可能的有效Clojure代码片段

事实证明,由于历史原因,Clojure阅读器是用Java编写的。由于它是一个重要的软件,运行良好,经过几年的大量调试和战斗测试,Rich Hickey决定在ClojureScript编译器中重用它(这是ClojureScript编译器在JVM上运行的主要原因)。ClojureScript编译过程主要发生在JVM上,在JVM上有Clojure阅读器,因此ClojureScript代码由
Clojure.core/read字符串
(或者更确切地说是它的近亲
Clojure.core/read
)函数解析

但是您的web应用程序无法访问正在运行的JVM。ClojureScript应用程序需要一个Java小程序看起来不是一个很有前途的想法,尤其是因为ClojureScript的主要目标是将Clojure语言的范围扩展到JVM(和CLR)之外。因此决定ClojureScript将无法访问其自己的阅读器,因此也无法访问其自己的编译器(即ClojureScript中没有
eval
read
read string
)。这个决定及其影响将由一个真正知道事情是如何发生的人进行更详细的讨论