MarshalJSON 具有嵌入式类型的类型以 {} 而不是值结束
MarshalJSON a type with an embedded type ends up as {} instead of the value
为了与 swagger 交互,我需要制作一个自定义的 BigInt
结构,它只是环绕 go 的 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()
,这会 return 0
。相反,我得到了这个输出:
{"sender_id":"alice","recipient_id":"bob","amount":{},"fee":{},"payload":"Hello World","ttl":10,"nonce":1}
但我真正想要的是:
{"sender_id":"alice","recipient_id":"bob","amount":10,"fee":10,"payload":"Hello World","ttl":10,"nonce":1}
而且我必须将这段代码添加到 BigInt
才能做到这一点:
func (b BigInt) MarshalJSON() ([]byte, error) {
return b.Int.MarshalJSON()
}
但根据 Effective Go's section on embedding structs,这根本没有必要。为什么 big.Int
显示为 {}
?
big.Int
implements a custom JSON marshaler (json.Marshaler
), see Int.MarshalJSON()
。但是这个方法有指针接收者,所以它只被使用/调用,如果你有一个指针值:*big.Int
.
并且您嵌入了一个非指针值,因此不会调用此自定义封送拆收器,并且由于 big.Int
是一个具有未导出字段的结构,您将在输出中看到一个空的 JSON 对象: {}
.
要使其工作,您应该使用指向您的类型的指针,例如:
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)
然后输出将是例如(在Go Playground上尝试):
{"sender_id":"alice","recipient_id":"bob","amount":0,"fee":0} <nil>
另一种选择是使用非指针 utils.BigInt
,但是 utils.BigInt
应该嵌入指针类型:
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)
并且输出将再次(在 Go Playground 上尝试):
{"sender_id":"alice","recipient_id":"bob","amount":0,"fee":0} <nil>
为了与 swagger 交互,我需要制作一个自定义的 BigInt
结构,它只是环绕 go 的 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()
,这会 return 0
。相反,我得到了这个输出:
{"sender_id":"alice","recipient_id":"bob","amount":{},"fee":{},"payload":"Hello World","ttl":10,"nonce":1}
但我真正想要的是:
{"sender_id":"alice","recipient_id":"bob","amount":10,"fee":10,"payload":"Hello World","ttl":10,"nonce":1}
而且我必须将这段代码添加到 BigInt
才能做到这一点:
func (b BigInt) MarshalJSON() ([]byte, error) {
return b.Int.MarshalJSON()
}
但根据 Effective Go's section on embedding structs,这根本没有必要。为什么 big.Int
显示为 {}
?
big.Int
implements a custom JSON marshaler (json.Marshaler
), see Int.MarshalJSON()
。但是这个方法有指针接收者,所以它只被使用/调用,如果你有一个指针值:*big.Int
.
并且您嵌入了一个非指针值,因此不会调用此自定义封送拆收器,并且由于 big.Int
是一个具有未导出字段的结构,您将在输出中看到一个空的 JSON 对象: {}
.
要使其工作,您应该使用指向您的类型的指针,例如:
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)
然后输出将是例如(在Go Playground上尝试):
{"sender_id":"alice","recipient_id":"bob","amount":0,"fee":0} <nil>
另一种选择是使用非指针 utils.BigInt
,但是 utils.BigInt
应该嵌入指针类型:
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)
并且输出将再次(在 Go Playground 上尝试):
{"sender_id":"alice","recipient_id":"bob","amount":0,"fee":0} <nil>