Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni
🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!01.04.2024
Декодування ненормального JSON у Go
Кастомизація розбору та генерації JSON у Go - один з підходів “вище середнього”, який робить цю типізовану мову зручнішою або взагалі, відкриває шлях до задач, які здаються неможливими.
Вчора зіткнувся з проблемкою: в JSON-LD в одних рецептах світлини передаються переліком об’єктів (в об’єктах - посилання, розмір, і т.д.), а в інших - просто рядком з посиланням.
В мовах з динамічним типізуванням це навіть не варто уваги. А в Go ми повинні задати конкретний тип JSON, який хочемо отримати. Та написати в ньому “рядок або масив обʼєктів” неможливо, бо в Go немає алгебраїчних типів.
Можна, як я колись писав, встановити тип interface{}
. Результат можна розібрати або рефлексією, або перевіркою типів; в будь-якому випадку код буде багатослівний. Особливо якщо дані мають складну структуру, а не просто “рядок або число”.
Однак є й кращий спосіб. Це створити спеціальний тип поля та реалізувати в ньому метод UnmarshalJSON. Метод отримує на вхід []byte
, та повинний призначити з них свій зміст. Не потрібно вручну парсити JSON; ми делегуємо це звичайному парсеру, коли зʼясуємо, який конкретний тип перед нами. Наприклад, в моєму випадку, я просто дивлюся, чи є перший символ лапкою "
, та викликаю Unmarshal
в рядок, а якщо ні — то в структуру.