2024 年 Clojure 状态调查!中分享您的想法。

欢迎!请查看关于页面,了解更多关于如何操作的信息。

+1

编辑

ClojureScript 将使用 JavaScript 唯一的数字类型 Number 来表示如 {:person/weight 200.0} 这样的数值。当这样的记录用 transit 序列化时,transit 会看到 Number: 200 并将其打包为一个整数,然后例如 JVM 这样的其他平台会将它解包为一个整数,而不是浮点数。而现在,如果 Datomic 这样的系统在没有预处理并根据一个表明 :person/weight 实际上是 :db.type/float 的模式进行处理的情况下接收到意外的类型,就可能会崩溃。

这是 transit 的设计缺陷吗?transit 应该改变以允许我指定类型或集成一个模式提供者(spec),以选择正确的类型吗?

1 答案

+1

我试图稍微重述一下您的问题,我相信您是在问,是否有某种方式可以使 transit-cljs (或者更确切地说 transit-js) 强制将 JavaScript 数字 200.0 编码为 transit 基础类型 "浮点小数"?(这实际上不是一个 transit-format 的问题,因为 transit 本身就有能力表示固定和任意精度的整数和浮点数。所以,这实际上是一个特定于语言的编码器问题。)

我认为答案是“否”(但我不是这个领域的js专家)。transit-js/transit-cljs 只能将 transit 基本类型编码为 i(整数,有符号64位)或 f(任意精度十进制)。我不知道,但我猜这可能是由于难以判断一个数值是否可以被表示为浮点十进制。

可能允许您强制执行此类操作,但我认为讨论这个问题的最佳地点可能是 https://github.com/cognitect/transit-js/issueshttps://github.com/cognitect/transit-cljs/issues

by
我认为Transit不可能在没有与类似于spec或Datomic这样的模式提供者集成的情况下,在哲学层面正确地完成其工作[跨平台值交换]?
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

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

看起来您的问题是因为数据库有一个严格的模式。所以我会在该级别简单地实现强制转换。
...