работа - parsing json golang




Как не маршалировать пустую структуру в JSON с Go? (2)

Как упоминалось в комментарии @chakrit, вы не можете заставить это работать, внедряя json.Marshaler в MyStruct , а реализация настраиваемой функции сортировки JSON для каждой структуры, которая ее использует, может быть намного более эффективной. Это действительно зависит от вашего варианта использования в отношении того, стоит ли вам дополнительной работы или готовы ли вы жить с пустыми структурами в своем JSON, но вот шаблон, который я использую для Result :

type Result struct {
    Data       MyStruct
    Status     string   
    Reason     string    
}

func (r Result) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct {
        Data     *MyStruct   `json:"data,omitempty"`
        Status   string      `json:"status,omitempty"`
        Reason   string      `json:"reason,omitempty"`
    }{
        Data:   &r.Data,
        Status: r.Status,
        Reason: r.Reason,
    })        
}

func (r *Result) UnmarshalJSON(b []byte) error {
    decoded := new(struct {
        Data     *MyStruct   `json:"data,omitempty"`
        Status   string      `json:"status,omitempty"`
        Reason   string      `json:"reason,omitempty"`
    })
    err := json.Unmarshal(b, decoded)
    if err == nil {
        r.Data = decoded.Data
        r.Status = decoded.Status
        r.Reason = decoded.Reason
    }
    return err
}

Если у вас есть огромные структуры со многими полями, это может стать утомительным, особенно изменив реализацию структуры позже, но не переписывая весь пакет json в соответствии с вашими потребностями (не очень хорошая идея), это в значительной степени единственный способ, которым я могу думать сделав это, сохраняя при этом не указатель MyStruct .

Кроме того, вам не нужно использовать встроенные структуры, вы можете создавать именованные. Я использую LiteIDE с завершением кода, поэтому я предпочитаю inline, чтобы избежать беспорядка.

У меня есть такая структура:

type Result struct {
    Data       MyStruct  `json:"data,omitempty"`
    Status     string    `json:"status,omitempty"`
    Reason     string    `json:"reason,omitempty"`
}

Но даже если экземпляр MyStruct полностью пуст (что означает, что все значения по умолчанию), он сериализуется как:

"data":{}

Я знаю, что в документах encoding/json указано, что «пустые» поля:

false, 0, любое значение nil или значение интерфейса, а также любой массив, срез, карта или строка с длиной нуля

но без учета структуры со всеми пустым значением / значением по умолчанию. Все его поля также помечены как omitempty , но это не имеет никакого эффекта.

Как я могу заставить пакет JSON не маршализовать мое поле, которое является пустой структурой?


Ой! Легкое исправление: «любой указатель нуля». - сделать struct указателем.

Fix:

type Result struct {
    Data       *MyStruct `json:"data,omitempty"`
    Status     string    `json:"status,omitempty"`
    Reason     string    `json:"reason,omitempty"`
}

Обратите внимание на *MyStruct - когда я создаю MyStruct сейчас, я просто делаю это по ссылке:

myStruct := &MyStruct{ /* values */ }

И теперь «пустой» MyStruct больше не сортируется в JSON по желанию.





go