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 本身具有表示固定和任意精度整数和浮点数的能力。因此,这实际上是一个特定语言编码器的问题。)

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

可能允许您强制这种做法,但我认为讨论这个问题最好的地方可能是在https://github.com/cognitect/transit-js/issueshttps://github.com/cognitect/transit-cljs/issues

Dustin Getz
我在哲学层面怀疑,除非与spec或Datomic这样的模式提供程序整合,Transit是无法正确执行其任务(跨平台值交换)的?
alexmiller
Transit的核心是提供一个无模式的值传输方式,允许编码(和扩展类型)。根据其原理,“Transit根据语义类型处理元素,但不是一个类型系统,也没有模式。” https://github.com/cognitect/transit-format#rationale Transit可以传输浮点值吗?是的,它有用于此的目的基本类型。

有关transit类型在不同语言中的编码或解码问题,应该在特定语言的编码器或解码器中进行讨论(因为语言特定的功能不同)。transit-cljs/transit-js有将JavaScript数字编码为浮点小数的机制吗?目前没有。

这些问题与我们讨论的模式或Datomic无关。
Dustin Getz
经过深思熟虑,我认为Transit所说的无模式目标关于解码和解释。您不需要模式来读取它。然而,在这种特定情况下,模式是必要的复杂性,有助于在写入端的奇特平台上。我认为。
by
在这种情况下,当反序列化到 JavaScript 时,您失去了信息,因为它的类型系统无法描述这种区别。所以这个数字现在实际上是一个整数。

(Number/isInteger 200.0)
;> true

所以从序列化的角度来看,看起来是正确的。

看起来似乎是因为你的数据库有一个严格的架构。所以我会简单地在那个级别实现强制转换。
...