3 回答

TA貢獻1946條經(jīng)驗 獲得超3個贊
如果不提供一些編組器,這將無法輕松處理。我知道您不想MarshalJSON手動編寫并完成所有操作,但是您可以嘗試在自定義編組器中擴展您的結(jié)構(gòu),而不是依賴默認編組器。概念證明:
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轉(zhuǎn)換rawUser為刪除所有方法 - 否則您將無限循環(huán)MarshalJSON. 此外,我選擇MarshalJSON對副本而不是指針進行操作,以確保json.Marshal(user)產(chǎn)生與json.Marshal(&user).
這不是單行代碼,而是隱藏了標準接口背后的復(fù)雜性,因此您無需記住有一種特殊的非標準方式將您的結(jié)構(gòu)轉(zhuǎn)換為 JSON。

TA貢獻1757條經(jīng)驗 獲得超8個贊
您可以創(chuàng)建一個新類型并將其編碼為 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 實現(xiàn)json.Marshaller,并在幕后User.MarshalJSON()創(chuàng)建一個UserForJSON對象,那就太好了,但這會導(dǎo)致無限遞歸。

TA貢獻1878條經(jīng)驗 獲得超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 關(guān)注
- 191 瀏覽
添加回答
舉報