为了账号安全,请及时绑定邮箱和手机立即绑定

Go - 自定义解组器 - 浮动字符串

Go - 自定义解组器 - 浮动字符串

Go
侃侃尔雅 2023-02-06 18:53:19
我使用第 3 方 API,以字符串形式提供价格,有 3 种口味://Input[    {"id": "A", "price": "123"},    {"id": "B", "price": "123.5"},    {"id": "C", "price": ""}]//Expected output[    A 123,    B 123.5,    C 0]我知道我可以,string在我的结构中添加该部分,但这不会处理订单 C。我发现了这个github 问题,其中询问了有关 int 的问题。那里有一个游乐场代码,我根据自己的需要做了一些改动。如果我将其更改为 float64 而不是 int,我会收到一个错误,订单 A 的日志现在为 0。json: cannot unmarshal string into Go struct field Order.price of type float64[{A 0}]我认为这if string(data) ==  '""' {部分代码将检查空字符串(大小写顺序 C),如果是:设置为 0。但"123"不是""。除了下面的部分,我还了解其余的自定义解组器。有人能指出我正确的方向吗?p := (*float64)(foe)*p = fpackage mainimport (    "encoding/json"    "fmt"    "strings")type StringToFloat float64type Order struct {    Id    string        `json:"id"`    Price StringToFloat `json:"price"`}func (foe *StringToFloat) UnmarshalJSON(data []byte) error {    if string(data) == `""` {        if foe != nil {            *foe = 0        }        return nil    }    var f float64    err := json.Unmarshal(data, &f)    if err != nil {        return err    }    p := (*float64)(foe)    *p = f    return nil}func main() {    jsonString := `[        {"id": "A", "price": "123"},        {"id": "B", "price": "123.5"},        {"id": "C", "price": ""}    ]`    var orders []Order    if err := json.NewDecoder(strings.NewReader(jsonString)).Decode(&orders); err != nil {        fmt.Println(err)    }    fmt.Println(orders)}
查看完整描述

1 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

尝试这个


package main


import (

    "encoding/json"

    "fmt"

    "strconv"

    "strings"

)


type StringToFloat float64


type Order struct {

    Id    string        `json:"id"`

    Price StringToFloat `json:"price"`

}


func (foe *StringToFloat) UnmarshalJSON(data []byte) error {

    if string(data) == "\"\"" {

        if foe != nil {

            *foe = 0

        }

        return nil

    }

    num := strings.ReplaceAll(string(data), "\"", "")

    n, err := strconv.ParseFloat(num, 64)

    if err != nil {

        return err

    }

    *foe = StringToFloat(n)

    return nil

}


func main() {

    jsonString := `[

        {"id": "A", "price": "123"},

        {"id": "B", "price": "123.5"},

        {"id": "C", "price": ""}

    ]`

    var orders []Order

    if err := json.NewDecoder(strings.NewReader(jsonString)).Decode(&orders); err != nil {

        fmt.Println(err)

    }


    fmt.Println(orders)

}

去游乐场:https ://go.dev/play/p/cHjNQ447eX9

注意事项:

  • UmarshalJSON func 的函数签名需要与 Decode 获取的给定函数签名完全相同。在您更新的代码error中缺少返回类型

  • string(data)给出"123"所以需要在之前删除引号ParseFloat

  • return nil在 string = ""check 之后是必需的,所以它不会走得更远


查看完整回答
反对 回复 2023-02-06
  • 1 回答
  • 0 关注
  • 71 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信