У Льоні сьогодні

Скорочення повторюваного коду на Go за допомогою кодогенерації

🐹🧙📑 Сьогодні рефакторив модуль на Go, в якому розплодився допоміжний код. Код такий, що не піддається звичайному розділенню на функції, а його треба копіювати з маленькими змінами багато разів. Тобто те, що називається boilerplate.

В Ruby таке вирішується метапрограмуванням. В JavaScript на функції можна розбити практично все. В Clojure код — це дані, тож проблема не існує концептуально. А що в Go робити?

Go - мова дуже проста. І з копіпастою справляється простим засобом — генерацією кода. Для цього є директива go generate. Її доцільно вжити, якщо ви бачите, що копіпаста не піддається рефакторингу.

Приклад задач, які я вирішував генерацією:

  • заміну складних обгорток CGO
  • генерацію сервера HTTP API з оголошень RPC
  • оптимізовані кодеки для формату MessagePack без рефлексії, бібліотекою go-codec
  • парсер для внутрішньої мови за допомогою бібліотеки pigeon.

Генерацію кода дуже просто написати, я зазвичай роблю шаблон — буквально модулем text/template. Нічого особливого в генераторах немає, це може будь-яка програма будь-якою мовою.

Нарешті, помічаємо файли як згенеровані, щоб GitHub їх приховував.