json.Marshal(struct) возвращает пустой JSON "{}": как исправить?
Почему json.Marshal() возвращает пустой объект?
Проблема в том, что поля вашей структуры User объявлены с неэкспортируемыми (приватными) именами. В Go поле считается экспортируемым (публичным), только если его имя начинается с заглавной буквы. Пакет encoding/json может сериализовать только экспортируемые поля — приватные поля игнорируются без ошибки.
В вашем примере поля Name и Age — с заглавных букв, поэтому они должны работать. Но если бы вы написали:
type User struct {
name string // приватное поле
age int // приватное поле
}
— тогда json.Marshal() действительно вернул бы {}.
Однако ваша структура корректна. Есть другая распространённая причина: вы случайно используете теги JSON с опцией -, которая исключает поле из сериализации. Проверьте, нет ли у вас такого:
type User struct {
Name string `json:"-"`
Age int `json:"-"`
}
Если это так — удалите теги или замените их на правильные:
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
Полное решение с пояснениями
Вот рабочий пример, который гарантированно выведет ожидаемый JSON:
package main
import (
"encoding/json"
"fmt"
)
type User struct {
Name string `json:"name"` // тег задаёт ключ в JSON
Age int `json:"age"` // если тег опущен — ключ = имя поля (Name)
}
func main() {
u := User{Name: "Alice", Age: 30}
result, err := json.Marshal(u)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(result)) // {"name":"Alice","age":30}
}
Проверка: что именно не так?
- Проверьте экспортируемость — имена полей должны начинаться с заглавной буквы.
- Проверьте теги JSON — если есть
json:"-", поле будет пропущено. - Используйте
json.MarshalIndentдля отладки — он покажет структуру. - Проверьте вложенные структуры — если поле само является структурой, его поля тоже должны быть экспортируемыми.
Если после всех проверок проблема остаётся — выложите точную копию вашего кода, возможно, есть опечатка или невидимый символ.
<<Альтернативный подход: используйте указатели или кастомную сериализацию
Иногда пустой JSON возникает из-за того, что поля структуры являются указателями или имеют нулевые значения (например, 0, "", nil). По умолчанию json.Marshal включает поля с нулевыми значениями, если не указан тег omitempty. Но если вы используете json:"fieldname,omitempty" и поле пустое — оно исчезнет из вывода.
Если вам нужно управлять форматом JSON вручную, реализуйте интерфейс json.Marshaler:
type User struct {
Name string
Age int
}
func (u User) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]interface{}{
"user_name": u.Name,
"user_age": u.Age,
})
}
Этот метод даёт полный контроль над выходным JSON. Также проверьте, не используете ли вы json.RawMessage или interface{} — они могут вести себя неожиданно.
Ответов пока нет.
Войдите чтобы оставить ответ