简体   繁体   English

Go正确编组float64到JSON吗?

[英]Does Go correctly marshal float64 to JSON?

Using go1.1.2 Win64, I have a Go program that "marshal"'sa struct containing a float64. 使用go1.1.2 Win64,我有一个Go程序,它“编组”包含float64的结构。 When the value of the float64 is not a whole number eg. 当float64的值不是整数时,例如。 1234.44, then it gets "marshal"ed as a float (json.Marshal). 1234.44,然后它被“编组”为浮点数(json.Marshal)。 When however it is a whole number eg. 然而,当它是一个整数时,例如。 "1234.00" it is marshalled as an integer"1234". “1234.00”它被编组为整数“1234”。 When I receive that at the other end (Dart), Dart (30188) treats the whole number as an integer (in map - JSON.decode). 当我在另一端(Dart)收到它时,Dart(30188)将整数视为整数(在地图中 - JSON.decode)。 Consequently the Dart program aborts when the representation of the float (double) data doesn't contain a decimal point, and I attempt to "extract" it from the map as a double. 因此,当float(double)数据的表示不包含小数点时,Dart程序将中止,并且我尝试将其从地图“提取”为double。

This can obviously be solved a number of different ways (eg. convert to integer and then convert back to float), however I wondered if there is another (better) way to handle this situation. 这显然可以通过许多不同的方式解决(例如,转换为整数然后转换回浮点数),但我想知道是否有另一种(更好的)方法来处理这种情况。

Is there another better way to handle this than to convert float64 to integer? 有没有比将float64转换为整数更好的方法来处理这个问题?

JSON, just like Javascript, doesn't differ between integers and numbers. JSON,就像Javascript一样,在整数和数字之间没有区别。

If Dart treats 1234.00 differently from 1234 , then it is making assumptions about the value not supported by the JSON specification . 如果Dart对1234.00处理1234.001234不同,则它会对JSON规范不支持的值进行假设。

While Go does indeed marshal float64 correctly, one way of getting around the problem with Dart's assumption is by implementing the Marshaler interface on your own type: 虽然Go确实正确地编组了float64,但解决Dart假设问题的一种方法是在你自己的类型上实现Marshaler接口

type Number float64

func (n Number) MarshalJSON() ([]byte, error) {
    // There are probably better ways to do it. It is just an example
    return []byte(fmt.Sprintf("%f", n)), nil
}

And then you can use your own Number type, instead of float64 , in the structs that you will Marshal. 然后你可以在你将要使用的结构中使用你自己的Number类型而不是float64 This way you can make sure that your numbers will always be marshaled with a decimal point. 这样,您可以确保您的数字始终以小数点编组。

Working example on Playground Playground上的工作示例

The following appears to be (to me) the solution. 以下似乎是(对我而言)解决方案。 The integer method toDouble() also works with "num" (or vice versa). 整数方法toDouble()也适用于“num”(反之亦然)。 It appears to me that when working with json and monetary values that could be interpreted as either double or int by Dart, that it is necessary to use "as num" and then use the built-in method toDouble(). 在我看来,当使用可以被Dart解释为double或int的json和货币值时,必须使用“as num”然后使用内置方法toDouble()。

Example (Go): 示例(Go):

type cuAcctRow struct {
         .....
    D_AcctBal    float64
         .....
}
    if baJsAcctDet, oOsError = json.Marshal(uAcctRow); oOsError != nil {

Example (Dart): 示例(Dart):

Map mAcctData = json.parse(sResponse);

double dAcctBal  = (mAcctData['D_AcctBal'] as num).toDouble();

I don't know why Dart doesn't allow direct assignment of integer to double, but I'm sure there is a good reason. 我不知道为什么Dart不允许将整数直接赋值为double,但我确信这是有充分理由的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM