MarshalJSON具有嵌入式类型的类型最终以{}代替值 [英] MarshalJSON a type with an embedded type ends up as {} instead of the value

查看:169
本文介绍了MarshalJSON具有嵌入式类型的类型最终以{}代替值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要与大摇大摆进行交互,我需要创建一个自定义的BigInt结构,该结构只不过围绕了go的big.Int.

To interact with swagger, I needed to make a custom BigInt struct which does nothing more than wrap around go's big.Int.

type BigInt struct {
    big.Int
}

...
type SpendTx struct {
    SenderID    string       `json:"sender_id,omitempty"`
    RecipientID string       `json:"recipient_id,omitempty"`
    Amount      utils.BigInt `json:"amount,omitempty"`
    Fee         utils.BigInt `json:"fee,omitempty"`
    Payload     string       `json:"payload,omitempty"`
    TTL         uint64       `json:"ttl,omitempty"`
    Nonce       uint64       `json:"nonce,omitempty"`
}

func (t SpendTx) JSON() (output []byte, err error) {
    return json.Marshal(t)
}

我希望SpendTx.JSON()最终会调用big.Int.MarshalJSON(),这将返回0.相反,我得到了以下输出:

I'd expect SpendTx.JSON() to eventually call big.Int.MarshalJSON(), which would return 0. Instead, I got this output:

{"sender_id":"alice","recipient_id":"bob","amount":{},"fee":{},"payload":"Hello World","ttl":10,"nonce":1}

但是我真正想要的是这个

But what I really want is this:

{"sender_id":"alice","recipient_id":"bob","amount":10,"fee":10,"payload":"Hello World","ttl":10,"nonce":1}

我必须将以下代码添加到BigInt中:

And I had to add this bit of code to BigInt to do it:

func (b BigInt) MarshalJSON() ([]byte, error) {
    return b.Int.MarshalJSON()
}

但是根据有效的Go的有关嵌入结构的部分,根本没有必要.为什么big.Int显示为{}?

But according to Effective Go's section on embedding structs, this shouldn't be necessary at all. Why is big.Int appearing as as {}?

推荐答案

big.Int 实现自定义JSON封送程序( json.Marshaler ),请参见 Int.MarshalJSON() .但是此方法具有指针接收器,因此只有在具有指针值:*big.Int.

并且您嵌入了一个非指针值,因此不会调用此自定义封送拆收器,并且由于big.Int是具有未导出字段的结构,因此您将在输出中看到一个空的JSON对象:{}.

And you embed a non-pointer value, so this custom marshaler is not called, and since big.Int is a struct with unexported fields, you will see an empty JSON object in the output: {}.

要使其正常工作,您应该使用指向您类型的指针,例如:

To make it work, you should use a pointer to your type, e.g.:

Amount      *utils.BigInt `json:"amount,omitempty"`
Fee         *utils.BigInt `json:"fee,omitempty"`

使用它的示例:

s := SpendTx{
    SenderID:    "alice",
    RecipientID: "bob",
    Amount:      &utils.BigInt{},
    Fee:         &utils.BigInt{},
}
data, err := s.JSON()
fmt.Println(string(data), err)

然后以输出为例(在进入游乐场上尝试):

Then output will be for example (try it on the Go Playground):

{"sender_id":"alice","recipient_id":"bob","amount":0,"fee":0} <nil>

另一种选择是使用非指针utils.BigInt,但是utils.BigInt应该嵌入一个指针类型:

Another option is to use the non-pointer utils.BigInt, but then utils.BigInt should embed a pointer type:

type BigInt struct {
    *big.Int
}

type SpendTx struct {
    Amount      utils.BigInt `json:"amount,omitempty"`
    Fee         utils.BigInt `json:"fee,omitempty"`
}

然后使用它:

s := SpendTx{
    SenderID:    "alice",
    RecipientID: "bob",
    Amount:      utils.BigInt{new(big.Int)},
    Fee:         utils.BigInt{new(big.Int)},
}
data, err := s.JSON()
fmt.Println(string(data), err)

然后将再次输出(在进入游乐场上尝试):

And output will be again (try it on the Go Playground):

{"sender_id":"alice","recipient_id":"bob","amount":0,"fee":0} <nil>

这篇关于MarshalJSON具有嵌入式类型的类型最终以{}代替值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆