如何将JSON转换为结构体(struct)

huangapple go评论65阅读模式
英文:

How to convert JSON to a struct

问题

我调用了一个第三方API,得到了以下的JSON数据:

{"amount":1.0282E+7}

当我想要将其转换时,出现了错误:

Blocjson: 无法将1.0282E+7解组为Go结构体字段MiddleEastAccountToCardResponse.amount,其类型为int64

我想将这个JSON转换为Go中的以下结构体:

type Response struct {
	Amount int64 `json:"amount"`
}
英文:

I call a third-party API and I get the following JSON:

{"amount":1.0282E+7}

When I want to convert it I got an error:

> Blocjson: cannot unmarshal number 1.0282E+7 into Go struct field MiddleEastAccountToCardResponse.amount of type int64

I want to convert this JSON to following struct in Go:

type Response struct {
	Amount int64 `json:"amount"`
}

答案1

得分: 1

由于您没有解释您确切的期望结果,我们只能猜测。但是,您有三种常见的方法可以实现这个目标:

  1. 将其解组为浮点类型而不是整数类型。如果需要整数,您可以稍后将其转换为整数。

  2. 将其解组为json.Number类型,该类型保留了完整的JSON表示及其精度,并且可以根据需要转换为整数或浮点数。

  3. 使用自定义的解组器,它可以为您将浮点数转换为整数类型。

这里演示了这三种方法:

package main

import (
	"fmt"
	"encoding/json"
)

const input = `{"amount":1.0282E+7}`

type ResponseFloat struct {
    Amount float64 `json:"amount"`
}

type ResponseNumber struct {
    Amount json.Number `json:"amount"`
}

type ResponseCustom struct {
    Amount myCustomType `json:"amount"`
}

type myCustomType int64

func (c *myCustomType) UnmarshalJSON(p []byte) error {
    var f float64
    if err := json.Unmarshal(p, &f); err != nil {
        return err
    }
    *c = myCustomType(f)
    return nil
}

func main() {
    var x ResponseFloat
    var y ResponseNumber
    var z ResponseCustom
    
    if err := json.Unmarshal([]byte(input), &x); err != nil {
        panic(err)
    }
    if err := json.Unmarshal([]byte(input), &y); err != nil {
        panic(err)
    }
    if err := json.Unmarshal([]byte(input), &z); err != nil {
        panic(err)
    }
    fmt.Println(x.Amount)
    fmt.Println(y.Amount)
    fmt.Println(z.Amount)
}

在 playground 上查看

英文:

Since you haven't explained your exact desired outcome, we can only guess. But you have three general approaches to this:

  1. Unmarshal to a float type instead of an integer type. You can perhaps convert to an int later, if you need an int.

  2. Unmarshal to a json.Number type, which preserves the complete JSON representation and its precision, and can be converted to an int or float as needed.

  3. Use a custom unmarshaler, which converts from a float to an int type for you.

All three are demonstrated here:

package main

import (
	"fmt"
	"encoding/json"
)

const input = `{"amount":1.0282E+7}`

type ResponseFloat struct {
    Amount float64 `json:"amount"`
}

type ResponseNumber struct {
    Amount json.Number `json:"amount"`
}

type ResponseCustom struct {
    Amount myCustomType `json:"amount"`
}

type myCustomType int64

func (c *myCustomType) UnmarshalJSON(p []byte) error {
    var f float64
    if err := json.Unmarshal(p, &f); err != nil {
        return err
    }
    *c = myCustomType(f)
    return nil
}

func main() {
	var x ResponseFloat
	var y ResponseNumber
	var z ResponseCustom
	
	if err := json.Unmarshal([]byte(input), &x); err != nil {
	    panic(err)
	}
	if err := json.Unmarshal([]byte(input), &y); err != nil {
	    panic(err)
	}
	if err := json.Unmarshal([]byte(input), &z); err != nil {
	    panic(err)
	}
	fmt.Println(x.Amount)
	fmt.Println(y.Amount)
	fmt.Println(z.Amount)
}

See it in the playground.

答案2

得分: 0

你的结构体中的Amount字段是一个int64类型,但你试图从字符串中解析的数字是一个float(科学计数法表示)。

尝试使用以下代码:

type Response struct {
    Amount float64 `json:"amount"`
}
英文:

Amount field in your struct is a int64, but number you're trying to parse from string is float (in scientific notation).

Try this:

type Response struct {
    Amount float64 `json:"amount"`
}

答案3

得分: 0

请注意,我是一个语言模型,无法直接运行代码。我可以帮助你理解和翻译代码。

你提供的代码是一个Go语言的示例,它将一个JSON字符串解析为一个结构体,并打印出其中的一个字段。

以下是修改后的代码:

package main

import (
	"encoding/json"
	"fmt"
)

func main() {

	var data = []byte(`{"amount":1.0282E+7}`)
	var res Response
	json.Unmarshal(data, &res)
	fmt.Println(res.Amount)

}

type Response struct {
	Amount float64 `json:"amount"`
}

输出结果为:

1.0282e+07

这段代码的功能是将JSON字符串 {"amount":1.0282E+7} 解析为一个名为 Response 的结构体,并打印出 Amount 字段的值。

希望这能帮到你!如果你有其他问题,请随时问我。

英文:

Modify your code as follows:

package main

import (
	"encoding/json"
	"fmt"
)

func main() {

	var data = []byte(`{"amount":1.0282E+7}`)
	var res Response
	json.Unmarshal(data, &res)
	fmt.Println(res)

}

type Response struct {
	Amount float64 `json:"amount"`
}

Output:

{1.0282e+07}

huangapple
  • 本文由 发表于 2021年8月16日 21:23:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/68803569.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定