没有调用MarshalJSON

时间:2016-08-26 10:47:26

标签: json go marshalling

我正在尝试使用界面自定义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)

显然EditionsMapEdition结构的地图:

var EditionsMap map[string]datamodel.Edition

问题是MarshalJSON函数显然从未被调用过。

可能我做错了,但我无法理解问题是什么,我的理解是我只需要实现该功能以便调用它。

1 个答案:

答案 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()

Spec: Method sets:

  

类型可能具有与之关联的方法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! } 的值确实方法*EditionMarshalJSON()包将正确调用它。请在Go Playground上尝试相关的工作示例。

另一种选择是使用值接收器定义json方法:

Edition.MarshalJSON()

这样,无论你是否编组指针或非指针值,它都会起作用,因为带有值接收器的方法是func (u Edition) MarshalJSON() ([]byte, error) 类型和相应Edition方法集的一部分。指针类型。请在Go Playground上尝试此变体的工作示例。