3 回答
TA贡献1946条经验 获得超3个赞
如果不提供一些编组器,这将无法轻松处理。我知道您不想MarshalJSON手动编写并完成所有操作,但是您可以尝试在自定义编组器中扩展您的结构,而不是依赖默认编组器。概念证明:
type User struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
func (u *User) FullName() string {
return fmt.Sprintf("%s %s", u.FirstName, u.LastName)
}
func (u User) MarshalJSON() ([]byte, error) {
type rawUser User // raw struct, without methods (and marshaller)
// Marshal rawUser with an extension
return json.Marshal(struct {
rawUser
FullName string `json:"full_name"`
}{rawUser(u), u.FullName()})
}
您需要强制User转换rawUser为删除所有方法 - 否则您将无限循环MarshalJSON. 此外,我选择MarshalJSON对副本而不是指针进行操作,以确保json.Marshal(user)产生与json.Marshal(&user).
这不是单行代码,而是隐藏了标准接口背后的复杂性,因此您无需记住有一种特殊的非标准方式将您的结构转换为 JSON。
TA贡献1757条经验 获得超8个赞
您可以创建一个新类型并将其编码为 JSON。如果包含 type 的匿名字段*User,则两者合并:
type UserForJSON struct {
*User
FullName string `json:"full_name"`
}
func NewUserForJSON(u *User) *UserForJSON {
return &UserForJSON{u, u.FullName()}
}
func main() {
u := &User{"John", "Smith"}
j, _ := json.Marshal(NewUserForJSON(u))
fmt.Print(string(j))
}
如果我们可以让 User 实现json.Marshaller,并在幕后User.MarshalJSON()创建一个UserForJSON对象,那就太好了,但这会导致无限递归。
TA贡献1878条经验 获得超4个赞
我不确定它是否是“最好”的方法,但它非常简单。
func (u User) FullNameMarshal() []byte {
u.FullName = u.FirstName + " " + u.LastName
uj, err := json.Marshal(&u)
if err != nil {
fmt.Println(err)
}
return uj
}
- 3 回答
- 0 关注
- 163 浏览
添加回答
举报