dongyou8368
2019-04-16 18:31
浏览 415

如何解组包含整数,浮点数和数字字符串的JSON?

I have a multiple different JSON requests of data that is being passed into my Go app that contains numbers in different formats. An example of a request is as follows:

{
    "stringData":"123456",
    "intData": 123456,
    "floatData": 123456.0
}

Is there a way to unmarshal this data into the type which is determined by the JSON data. For example, string data would be "123456", int data would be 123456 and float data would be 123456.0. I do not have structs defined for these JSON objects and creating structs for these are not an option.

I have looked at the decoder.UseNumber() method to convert the data into strings, but I don't know how to handle the difference between stringData and intData after that.

图片转代码服务由CSDN问答提供 功能建议

我有多个不同的JSON数据请求,这些请求将传递到Go应用程序中,其中包含不同格式的数字。 请求的示例如下:

  {
“ stringData”:“ 123456”,
“ intData”:123456,
“ floatData”:123456.0 \  n} 
   
 
 

是否可以将数据解组为由JSON数据确定的类型。 例如,字符串数据将为“ 123456”,整数数据将为123456,浮点数据将为123456.0。 我没有为这些JSON对象定义结构,也不为这些对象创建结构。

我已经看过了encoder.UseNumber()方法,将数据转换为字符串,但是 之后,我不知道如何处理stringData和intData之间的差异。

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • doujiong9915 2019-04-16 22:59
    已采纳

    Decode to map[string]interface{} with the UseNumber option. Use a type assertion to find numbers and convert based on presence of the ".".

    dec := json.NewDecoder(r)
    dec.UseNumber()
    
    var m map[string]interface{}
    err := dec.Decode(&m)
    if err != nil {
        log.Fatal(err)
    }
    
    for k, v := range m {
        v, err := decodeValue(v)
        if err != nil {
            log.Fatal(err)
        }
    for k, v := range m {
        v, err := decodeValue(v)
        if err != nil {
            log.Fatal(err)
        }
        switch v := v.(type) {
        case string:
            fmt.Printf("%s is a string with value %q
    ", k, v)
        case int64:
            fmt.Printf("%s is a integer with value %d
    ", k, v)
        case float64:
            fmt.Printf("%s is a float with value %f
    ", k, v)
        default:
            fmt.Printf("%s is a %T with value %v
    ", k, v, v)
        }
    }
    
    
    ...
    
    func decodeValue(v interface{}) (interface{}, error) {
        if vv, ok := v.(json.Number); ok {
            if strings.Contains(vv.String(), ".") {
                return vv.Float64()
            } else {
                return vv.Int64()
            }
        } else {
            return v, nil
        }
    }
    

    Run it on the playground.

    This example prints what's found and exits the program on error. If your goal is to create a map with the values of the correct types, then replace the code that prints numbers with m[k] = n.

    已采纳该答案
    打赏 评论
  • drqn5418 2019-04-16 19:25

    You can unmarshal the json to a map[string]interface{} and then cast to the correct types using a type switch.

    打赏 评论

相关推荐 更多相似问题