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

我使用第 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 = f

package main


import (

    "encoding/json"

    "fmt"

    "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

    }


    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)

}


侃侃尔雅
浏览 97回答 1
1回答

斯蒂芬大帝

尝试这个package mainimport (    "encoding/json"    "fmt"    "strconv"    "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    }    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"所以需要在之前删除引号ParseFloatreturn nil在 string = ""check 之后是必需的,所以它不会走得更远
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go