未调用 MarshalJSON
MarshalJSON not called
我正在尝试使用界面自定义 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
s 结构的映射:
var EditionsMap map[string]datamodel.Edition
问题是 MarshalJSON
函数显然从未被调用过。
可能我做错了什么,但我不明白问题出在哪里,我的理解是我只需要实现该函数才能调用它。
这是因为您使用 指针 接收器声明了 Edition.MarshalJSON()
方法:
func (u *Edition) MarshalJSON() ([]byte, error)
并且您尝试编组非指针值(您的映射包含 datamodel.Edition
个值):
var EditionsMap map[string]datamodel.Edition
// ...
json.NewEncoder(w).Encode(EditionsMap)
带有指针接收者的方法不属于相应非指针类型的方法集。类型datamodel.Edition
的方法集不包含方法MarshalJSON()
.
A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T
consists of all methods declared with receiver type T
. The method set of the corresponding pointer type *T
is the set of all methods declared with receiver *T
or T
(that is, it also contains the method set of 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()
将被 json
包正确调用。在 Go Playground.
上尝试一个工作示例
另一种选择是使用值 receiver:
定义 Edition.MarshalJSON()
方法
func (u Edition) MarshalJSON() ([]byte, error)
并且无论您编组指针值还是非指针值,这种方式都可以工作,因为具有值接收者的方法是 Edition
类型和相应 [=24] 类型方法集的一部分=] 指针类型。在 Go Playground.
上尝试此变体的工作示例
我正在尝试使用界面自定义 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
s 结构的映射:
var EditionsMap map[string]datamodel.Edition
问题是 MarshalJSON
函数显然从未被调用过。
可能我做错了什么,但我不明白问题出在哪里,我的理解是我只需要实现该函数才能调用它。
这是因为您使用 指针 接收器声明了 Edition.MarshalJSON()
方法:
func (u *Edition) MarshalJSON() ([]byte, error)
并且您尝试编组非指针值(您的映射包含 datamodel.Edition
个值):
var EditionsMap map[string]datamodel.Edition
// ...
json.NewEncoder(w).Encode(EditionsMap)
带有指针接收者的方法不属于相应非指针类型的方法集。类型datamodel.Edition
的方法集不包含方法MarshalJSON()
.
A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type
T
consists of all methods declared with receiver typeT
. The method set of the corresponding pointer type*T
is the set of all methods declared with receiver*T
orT
(that is, it also contains the method set ofT
).
尝试整理指针值,定义您的映射以包含指针:
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()
将被 json
包正确调用。在 Go Playground.
另一种选择是使用值 receiver:
定义Edition.MarshalJSON()
方法
func (u Edition) MarshalJSON() ([]byte, error)
并且无论您编组指针值还是非指针值,这种方式都可以工作,因为具有值接收者的方法是 Edition
类型和相应 [=24] 类型方法集的一部分=] 指针类型。在 Go Playground.