Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni
🤖🚫 Контент вільний від AI. Цей пост на 100% написаний людиною, як і все на моєму блозі. Насолоджуйтесь!09.08.2024
Дженерики та кодогенерація в Golang
Я люблю генерацію коду як аналог метапрограмування на Go. Навіть більше, ніж метапрограмування як у Ruby, оскільки згенерований код можна переглянути, а не тільки уявити.
Дженерики частково прибрали потребу в кодогенерації: а саме, більше не потрібно генерувати код “з підставлянням типів”. Це чудово та, звісно, в нашому коді є місце дженерикам. (Хоча я поки не брався за впровадження суто функціональних підходів, як, наприклад робить модуль github.com/samber/lo.)
Але все ж навіть з дженериками залишається багато шаблонного коду, який неможливо узагальнити. Уявимо, що у нас є структура Database
, в якій 10 різних полів Table[Key, Record]
. Всі ці поля доведеться оголосити, ініціалізувати, та виконати різне обслуговування. Щоб не копіювати десять разів однакові рядки для кожної таблиці, нам і допоможе кодогенерація.
Раніше я передавав параметри генератора в рядку //go:generate
, але нещодавно знайшов інший підхід. Можна почати з конфігурації у JSON чи TOML, а у генераторі зчитувати ту конфігурацію та генерувати весь код. Наприклад, в конфігурації може бути список таблиць, за яким ми генеруємо і структуру Database
, і функцію Database.SaveTables()
, і все інше.
Можливості практично необмежені! Але все ж я б радив зводити генерований код до мінімуму, бо код в шаблоні точно важче сприймати та редагувати. Наприклад, замість генерації всієї Database
можна згенерувати структуру tables
та вбудувати її: type Database struct { tables }
. Тоді цей тип можна розширювати без вдавання до шаблону.