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/issues) 或 [链接](https://github.com/cognitect/transit-cljs/issues)。

我在哲学层面上质疑Transit不能在没有与spec或Datomic这样的模式提供者集成的情况下正确完成其工作[跨平台值交换]?
Transit的整个目的就是提供一个无模式的传输值的方法,提供一种编码(和扩展类型)的手段。据其原理,“Transit以语义类型处理元素,但它不是一个类型系统,也没有模式。” [链接](https://github.com/cognitect/transit-format#rationale) 可以Transit传输浮点值吗?是的,它有一个基本类型用于此。

有关transit类型按语言编码或解码的问题应向特定语言的编码器或解码器提问(因为语言特定的功能有所不同)。transit-cljs/transit-js有方法将JavaScript数字编码为浮点十进制数吗?不,目前没有。

这些问题与模式或Datomic无关。
经过思考,我认为Transit提出的无模式目标是关于解码和解释。你不需要模式来读取它。然而,在这种情况下,模式对于帮助奇特的写入平台是必要的。我认为
by
在这种情况下,当反序列化到JS时,你已经丢失了信息,因为其类型系统无法建模这种区别。所以这个数字现在实际上是一个整数。

(Number/isInteger 200.0)
;> true

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

看起来好像你的数据库具有严格的模式。因此,我建议在这个级别实施强制转换。
...