Названия ключей JSON в нижнем регистре с помощью JSON Marshal в Go


175

Я хочу использовать "encoding/json"пакет, чтобы упорядочить структуру, объявленную в одном из импортированных пакетов моего приложения.

Например.:

type T struct {
    Foo int
}

Поскольку он импортируется, все доступные (экспортируемые) поля в структуре начинаются с заглавной буквы. Но я хотел бы иметь имена ключей в нижнем регистре:

out, err := json.Marshal(&T{Foo: 42})

приведет к

{ "Foo": 42}

но я хочу получить

{ "Foo": 42}

Можно ли обойти проблему каким-то простым способом?


5
@Zippoxer: я бы сказал: ключ в протоколе связи клиент / сервер, строго определенный для строчных букв. Ну, в моем случае это не имеет значения, так как я сам определил протокол ... но по крайней мере в теории? Но я знаю, что в основном я трачу слишком много времени на глупые мелочи.
— ANisus

Не извиняйся. Вы не глупый, язык, который не принимает полную спецификацию json, является глупым (хотя проблема легко решается, как показано ниже).
— Джехан

@ANisus: Я неправильно понял ваш вопрос, касающийся имен структурных ключей, а не имен ключей JSON. Отказался от голосования.
— Хлипкий

Ответы:


266

Посмотрите документы для кодирования / json.Marshal . В нем обсуждается использование тегов struct field для определения того, как сгенерированный json отформатирован.

Например:

type T struct {
    FieldA int    `json:"field_a"`
    FieldB string `json:"field_b,omitempty"`
}

Это сгенерирует JSON следующим образом:

{
    "field_a": 1234,
    "field_b": "foobar"
}

8
Полевые теги? Боже мой ... Я пропустил всю эту часть при поиске в документах. Я искал флаги, функции или некоторые другие настройки. Ну, это именно тот ответ, который я искал! И, кроме того, у меня есть новая концепция Go для изучения: теги полей :)
— ANisus

Они довольно удобны. Вы можете получить к ним доступ во время выполнения через reflectпакет.
— Джимт

Да, когда я работаю с отражением, я вижу, как способ добавить метаданные в поле может быть замечательной вещью! Кстати, только что попробовал ответ. Работает как шарм.
— ANisus

5
Я только начал ругать язык go - насколько это глупо, зачем им создавать поля с строчными буквами в сгенерированном JSON и т. Д., И т. Д. Затем я наткнулся на эту тему и подумал: «OMG Это великолепно !!!». Я даже вскочил и объяснил своей девушке, почему я так взволнован: D Это так круто :)))
— nyxz

11
Убедитесь, что между двоеточием и первой кавычкой тега нет пробела! Используйте json:"some_tag"вместо json: "some_tag". Я получил немного на некоторое время.
— Дэвид Моралес

8

Вы можете создать свою собственную структуру с ключами, которые вы хотите экспортировать, и дать им соответствующие теги json для строчных имен. Затем вы можете скопировать желаемую структуру в свою, прежде чем кодировать ее как JSON. Или, если вы не хотите создавать локальную структуру, вы, вероятно, можете создать map[string]interface{}и закодировать ее.


Глупо то, что другой пакет (содержащий типы) на самом деле тоже мой. Но, да, я, наверное, слепо смотрел на то, что это должна быть структура. Использование map[string]interface{}будет работать до тех пор, пока я не
— получу

1
@ ANisus: О, мой ответ основывался на том, что вы не контролируете определение структуры. Ответ Джимта определенно то, что вы хотите.
— Лили Баллард

Да, мне не было ясно, был ли это внешний пакет или нет. Но ваш ответ по-прежнему актуален и полезен в тех случаях, когда вы не контролируете определения.
— ANisus
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.