有没有一种方法可以使用bs-json对大于32位的整数值进行编码



我一直在使用字符串来表示大于32位的解码JSON整数。似乎string_of_int能够处理大的整数输入。因此,一个解码器,写(在Json.Decode命名空间中(:

id: json |> field("id", int) |> string_of_int,  /* 'id' is string */

正在成功处理至少37位的整数。

另一方面,编码对我来说很麻烦。远程服务器不接受字符串表示,并且需要int64。是否可以使bs-json支持int64类型?我希望这样的东西能起作用:

type myData = { id: int64 };
let encodeMyData = (data:myData) => Json.Encode.(object_([("id", int64(myData.id)]))

必须滚动我自己的编码器并不像解码器那么可怕,但是。。。我宁愿不要。

您没有确切说明编码有什么问题。int编码器除了更改类型之外什么也不做,因为它相信int值实际上是有效的。所以我认为是int_of_string操作造成了问题。但这就引出了一个问题,如果你能成功地将其解码为int,为什么要将其转换为string

这里的根本问题是JavaScript没有64位整数。最大安全整数是253-1。JavaScript实际上根本没有整数,只有floats,它可以表示一定范围的整数,但除非将它们转换为32位或64位的ints,否则无法有效地进行整数运算。因此,无论出于何种原因,可能是一致的溢出处理,在EcmaScript规范中决定二进制逐位操作应当对32位整数进行操作。因此,这开启了内部32位表示的可能性,创建32位整数的符号,以及优化整数运算的可能性。

因此,对于您的问题:

它会是"安全";只添加外部int64:int64->Js。Json.t="%"身份;到编码器文件?

不,因为JavaScript中没有64位整数表示,所以int64值表示为两个Number的数组,我相信这也是一个可能更改的内部实现细节。仅仅将其强制转换为Js.Json.t不会产生您期望的结果。

那么你能做什么

我建议使用float。在大多数方面,这将表现得与JavaScript数字完全一样,让您可以访问其全部范围。

或者,您可以使用nativeint,它的行为应该与floats类似,除了除法,除法的结果被截断为32位整数。

最后,您还可以直接使用几个轻量级JavaScript函数来实现自己的int_of_string,以创建一个技术上超出范围的int,尽管我不建议这样做:

let bad_int_of_string = str => 
str |> Js.Float.fromString |> Js.Math.floor_int;

相关内容

  • 没有找到相关文章

最新更新