我正在尝试使用界面自定义MarshalJSON
的输出:
func (m *RawMessage) MarshalJSON() ([]byte, error)
我遵循了该教程:http://choly.ca/post/go-json-marshalling/
我的目的是删除用true / false替换其中一个字段(如果设置或不设置),所以我最终编写了该函数:
func (u *Edition) MarshalJSON() ([]byte, error) {
var vaultValue bool
vaultValue = true
var onlineValue bool
vaultValue = false
fmt.Println("here")
if u.Vault == nil {
vaultValue = false
}
if u.Online == nil {
onlineValue = false
}
type AliasEdition Edition
return json.Marshal(&struct {
Vault bool `json:"vault,omitempty"`
Online bool `json:"online,omitempty"`
*AliasEdition
}{
Vault: vaultValue,
Online: onlineValue,
AliasEdition: (*Alias)(u),
})
}
JSON是使用以下指令从地图创建的:
json.NewEncoder(w).Encode(EditionsMap)
显然EditionsMap
是Edition
结构的地图:
var EditionsMap map[string]datamodel.Edition
问题是MarshalJSON
函数显然从未被调用过。
可能我做错了,但我无法理解问题是什么,我的理解是我只需要实现该功能以便调用它。
答案 0 :(得分:10)
这是因为您使用指针接收器声明了Edition.MarshalJSON()
方法:
func (u *Edition) MarshalJSON() ([]byte, error)
您尝试编组非指针值(您的地图包含datamodel.Edition
值):
var EditionsMap map[string]datamodel.Edition
// ...
json.NewEncoder(w).Encode(EditionsMap)
带指针接收器的方法不是相应非指针类型的方法集的一部分。类型datamodel.Edition
的方法集不包含方法MarshalJSON()
。
类型可能具有与之关联的方法。 interface type的方法集是其接口。 任何其他类型
T
的方法集包含使用接收方类型T
声明的所有methods。相应pointer type {{的方法集1}}是使用接收器*T
或*T
声明的所有方法的集合(也就是说,它还包含T
的方法集。)
尝试编组指针值,定义地图以包含指针:
T
指针类型var EditionsMap map[string]*datamodel.Edition
// ...
if err := json.NewEncoder(w).Encode(EditionsMap); err != nil {
panic(err) // HANDLE error somehow, do not omit it like in your example!
}
的值确实方法*Edition
,MarshalJSON()
包将正确调用它。请在Go Playground上尝试相关的工作示例。
另一种选择是使用值接收器定义json
方法:
Edition.MarshalJSON()
这样,无论你是否编组指针或非指针值,它都会起作用,因为带有值接收器的方法是func (u Edition) MarshalJSON() ([]byte, error)
类型和相应Edition
方法集的一部分。指针类型。请在Go Playground上尝试此变体的工作示例。