Каков наилучший способ назначить дополнительное поле для структуры, и все это ссылается на подструктуру при кодировании его из байта [], и это поле не является частью байта unmarshalling []?
Позвольте мне уточнитьпо примеру ...
- У нас есть несколько структур:
type Update struct {
UpdateID int32 `json:"update_id"`
Message *Message `json:"message,omitempty"`
...
}
type Message struct {
MessageID int32 `json:"message_id"`
From *User `json:"from,omitempty"`
Date int32 `json:"date"`
Chat Chat `json:"chat"`
...
}
Наша основная структура APIClient и имеет много методов для отправки или получения чего-либо (обертка API)
type API struct {
Token string
PollInt int32
URL string
client *http.Client
}
func(a *API) ... () {
}
func(a *API) ... () {
}
...
Основной цикл цикла делает запрос http и возвращает ответ json в виде «res» - [] байта, поэтому мы можем использовать json.Unmarshal для сопоставления его со специальной структурой обновления
func (a *API) GetUpdates(ctx context.Context, gu *GetUpdates) ([]Update, error) {
buf := bytes.Buffer{}
err := json.NewEncoder(&buf).Encode(gu)
if err != nil {
return nil, fmt.Errorf("getupdates: %s", err)
}
res, err := a.DoRequest(&ctx, "getUpdates", &buf)
if err != nil {
return nil, fmt.Errorf("getupdates: %s", err)
}
var result []Update
err = json.Unmarshal(res.Result, &result)
if err != nil {
return nil, fmt.Errorf("getupdates: %s", err)
}
return result, nil
}
Можно ли как-нибудь расширить ВСЕ структуры в цепочке немаркетинга для дополнительного поля при использовании json.Unmarshal
type Update struct {
UpdateID int32 `json:"update_id"`
Message *Message `json:"message,omitempty"`
...
API `json:"-"`
}
type Message struct {
MessageID int32 `json:"message_id"`
From *User `json:"from,omitempty"`
Date int32 `json:"date"`
Chat Chat `json:"chat"`
...
API `json:"-"`
}
Так что мы можем сделать что-то вроде:
var result []Update
err = json.Unmarshal(res.Result, &result, api)
if err != nil {
return nil, fmt.Errorf("getupdates: %s", err)
}
А затем используйте его:
result[0].RejectUpdate()
result[0].Message.SendReply()
...
func (u *Update) RejectUpdate(cause string) {
m.API.SendMessage(u.Chat.ID, text)
m.API.Reject(u.ID, cause)
}
func (m *Message) SendReply(text string) {
m.API.SendMessage(m.Chat.ID, text)
}
Вся структура будет расширена API (встроенная структура) при немаршалинге ...
Мои мысли о решении:
- Патч стандартного кодирования / библиотека json - не лучший выбор
- Получить пользовательскую библиотеку кодирования и немного переписать - сомнительный выбор
- Вручную демонтировать весь объект - ужасный код
type Bot struct {
superCLient string
}
type Image struct {
Name string
Path string
*Bot `json:"-"`
}
type FormFile struct {
Img *Image
Name string
*Bot `json:"-"`
}
func main() {
data := []byte(`{"Img": {"Name": "Vi", "Path": "/etc/log"}, "Name": "Josh"}`)
bot := &Bot{
superCLient: "ClientExample",
}
var omg FormFile
omg.CustomUnmarshal(data, bot)
fmt.Println(omg)
}
func (ff *FormFile) CustomUnmarshal(data []byte, bot *Bot) error {
var f map[string]*json.RawMessage
json.Unmarshal(data, &f)
var i Image
i.CustomUnmarshal(*f["Img"], bot)
ff.Img = &i
json.Unmarshal(*f["Name"], ff.Name)
ff.Bot = bot
return nil
}
func (img *Image) CustomUnmarshal(data []byte, bot *Bot) error {
err := json.Unmarshal(data, img)
img.Bot = bot
return err
}