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

欢迎!请查阅关于页面了解有关其工作的一些更多信息。

+1 投票

编辑

ClojureScript 使用 JavaScript 的唯一数值类型 Number 来表示诸如 {:person/weight 200.0} 这样的数值。当这样的记录被 transit 序列化时,transit 会将 Number: 200 视为一个整数,并将其打包,然后其他平台,如 JVM,会将其解包为一个整数,而不是一个浮点数。除非我预先根据声明 :person/weight 事实上是 :db.type/float 的模式对值进行预处理,否则像 Datomic 这样 Memories 系统将在意外的类型上崩溃。

这是 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中进行讨论。

我认为,除非与像spec或Datomic这样的模式提供者集成,否则Transit无法正确完成其工作(跨平台值交换)的哲学层面有疑问?
Transit的整个目的是通过提供编码(和扩展类型)的方式无模式地传输值。根据其原理,“Transit在语义类型的术语中处理元素,但它不是一个类型系统,也没有模式。”https://github.com/cognitect/transit-format#rationale Transit可以传输浮点值吗?是的,它有其基础类型。

有关transit类型的特定语言编码或解码的问题,应该由特定的语言编码器或解码器回答(因为特定语言的機能各不相同)。transit-cljs/transit-js有没有将JavaScript数字编码为浮点十进制的方法?目前没有。

据我所知,这些问题与模式或Datomic无关。
经过思考,我认为Transit声称的无模式目标是关于解码和解析。你不需要模式来读取它。然而,在这方面,模式是必要的复杂性,有助于解决写端上的一个特殊平台。我认为。
在这种情况下,由于其类型系统无法区分,在反序列化到JS时,您丢失了信息。因此,这个数字现在实际上是一个整数。

(Number/isInteger 200.0)
> true

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

似乎发生的事情是您的数据库具有严格的架构。因此,我会在该级别简单地实现强制转换。
...