请在2024 Clojure 状态调查!分享您的想法。

欢迎!请参阅关于页面了解更多信息。

+1 点赞

编辑

ClojureScript 会用 JavaScript 的唯一数值类型 Number 来表示像 {:person/weight 200.0} 这样的数值。当这样的记录使用 transit 进行序列化时,transit 会将 Number: 200 视为一个整数,并将其打包,然后其他平台如 JVM 会将这个整数拆包,而不是浮点数,如果没有预处理值以符合说明 :person/weight 实际上是 :db.type/float 的模式,像 Datomic 这样的系统会因为不预期的类型而崩溃。

这是 transit 的设计缺陷吗?transit 是否应该改变,以便我可以指定类型和/或集成到模式提供程序(spec)中,以选择正确的类型?

1 个答案

+1 点赞

我想稍微重申一下您的问题,我认为您是在问,transit-cljs(或更确切地说是transit-js)是否有办法强制将 JavaScript 的数字 200.0 编码为 transit 基础类型“浮点十进制”?(这其实不是一个 transit-format 问题,因为 transit 本身已经有能力表示固定和任意精度的整数和浮点数。所以这实际上是一个特定语言的编码器问题。)

我认为答案是“否”(但我不是 JavaScript 那边的专家)。transit-js/transit-cljs 只对作为 transit 基础类型的 i(整数,有符号 64 位)和 f(任意精度十进制)进行编码。我不知道,但我猜测这可能是因为很难判断一个数字是否可以表示为浮点十进制。

可能允许你强制性实现这样的功能。但我认为最合适的讨论地点可能是 https://github.com/cognitect/transit-js/issueshttps://github.com/cognitect/transit-cljs/issues.

by
我在哲学层面质疑,除非与spec或Datomic等模式提供程序集成,Transit怎么可能正确完成其工作[跨平台交换值]?
by
Transit的整個目的是成为一个无模式的值传输方法,通过提供编码(和扩展类型)的途径。按照理性,“Transit将元素根据语义类型进行处理,但它不是一种类型系统,也没有模式。” https://github.com/cognitect/transit-format#rationale Transit可以传输浮点值吗?是的,它为此提供了一个基本类型。

有关特定语言编码或解码Transit类型的问题,是针对那些特定语言编码器或解码器的问题(因为特定语言的功能各有不同)。transit-cljs/transit-js是否有将JavaScript数字编码为浮点小数的方法?目前没有。

这些问题与模式或Datomic没有任何关系。
by
经过思考,我认为Transit声明的无模式目标与解码和解释有关。你不需要模式来读取它。然而,在这种情况下,模式对于帮助奇特的写入端的内部复杂性是必要的。
by
在这种情况下,您在将数据反序列化为 JS 时丢失了信息,因为其类型系统无法区分这一点。因此,这个数字现在是整数。

(Number/isInteger 200.0)
;> true

因此,从序列化的角度来看,这似乎是正确的。

可能发生的情况是您的数据库有一个严格的模式。因此,我建议在该层面进行强制转换。
...