为了账号安全,请及时绑定邮箱和手机立即绑定

将自定义 JSON Marshal() 用于嵌入式结构的问题

将自定义 JSON Marshal() 用于嵌入式结构的问题

Go
斯蒂芬大帝 2021-11-22 15:55:26
我正在尝试定义一个自定义 JSON 封送拆收器来以特定格式显示一些时间信息。理想情况下,我想要一个结构来存储创建/修改的值,然后将它们嵌入到需要跟踪该信息的结构中。此外,我想在 JSON 封送拆收器中定义自定义日期格式,以便在客户端应用程序中使用。我目前有两个结构type Timestamp struct {    Created time.Time    Modified time.Time}type Company struct {    Id string    Name string    Timestamp    }我想将 Timestamp 结构嵌入到更新/创建项目时需要记录的对象中。那里没有什么疯狂的。当我定义时,我的问题就出现了func (t Timestamp) MarshalJSON() ([]byte, error) {    return json.Marshal(struct {        CreatedFormatted string    }{        CreatedFormatted: t.Created.Format("Monday Jan _2 15:04:05 2006"),    })}当我去 marshal 时Company,我只看到时间戳的 json,但没有看到公司的任何内容。我原以为会显示Company 结构和Timestamp 结构的内容。我在这里做错了吗?
查看完整描述

2 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

当嵌入在结构中的类型提供方法时,该方法成为嵌入结构的一部分。由于Companyembeds TimestampTimestamp'sMarshalJSON也可用于Company。当 json 正在寻找编组 a 时,Company它看到它有一个MarshalJSON方法并调用它——而它找到的方法只编组了时间戳字段。结构的默认行为(将每个字段编组为 JSON 对象中的自己的键)被覆盖。

你可以做什么:

  1. 不要使用结构嵌入,只需创建Timestamp一个常规字段(即使您将其声明为Timestamp Timestamp)。然后Company不会继承其方法,JSON 将按预期工作(但您的代码的其他部分希望嵌入可能会更改)。或者:

  2. 给出Company自己的MarshalJSON方法来编组包括时间戳在内的所有字段。你可以做到这一点
    。将字段复制到与Company嵌入相同但没有嵌入的不同类型中,并对其进行编组。
    湾 将字段复制到地图中并对其进行编组。
    C。独立编组每个字段并自己粘贴字符串。fmt.Sprintf({"key1":%s,"key2":%s,...}, m1, m2, ...)


查看完整回答
反对 回复 2021-11-22
?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

通过嵌入Timestamp,Company您不仅可以共享成员变量,还可以嵌入方法。这意味着您提供了Company.MarshalJSON方法,然后json包使用它来编组整个结构。为了查看所有字段,您还需要为Company结构实现显式封送拆收器。


如果您只想以特定方式格式化时间戳,另一种解决方案是提供您自己的time.Time并在那里提供 JSON marshaller。


例如:


type AccessTime time.Time


func (t AccessTime) MarshalJSON() ([]byte, error) {

    return json.Marshal(time.Time(t).Format("Monday Jan _2 15:04:05 2006"))

}


type Timestamp struct {

    Created  AccessTime

    Modified AccessTime

}

https://play.golang.org/p/PhZXPauSyz


查看完整回答
反对 回复 2021-11-22
  • 2 回答
  • 0 关注
  • 174 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信