Я только что сделал библиотеку, которая помогает мне работать со структурами, ничего не зная о том, что внутри структуры. Я работаю над SDK, которые реализуют разные HTTP API, и эти API полны различных моделей как для частичного запроса, так и для ответа. Если я хотел проверить, например, что структура содержит данный элемент, мне всегда приходилось создавать метод для данной структуры или любую проверку, необходимую для записи в структуру. Я хотел сделать это без головной боли, поэтому у меня всегда была какая-то специфическая функция SDK, которая могла бы обрабатывать всю структуру внутри SDK. Но с этим было сложно справиться, всегда вставлял их в новый SDK и форматировал под требования.

Когда я начал работать над этой библиотекой, я сначала проверил встроенный пакет строк, какие методы у него есть, и попытался сделать что-то подобное. Первый метод, который я действительно хотел реализовать, - это метод contains, который получает структуру и значение в виде интерфейса {}.

Содержит функцию

Таким образом, функция contains проверила, что данное значение содержит структуру. Делюсь кодом и после напишу подробности.

Во-первых, я использую reflection.ValueOf в структуре, чтобы определить, что это такое. Функция ValueOf инициализирует конкретное значение, хранящееся в интерфейсе, и возвращает его обратно как тип lect.Value. Все было бы проще, если бы мы могли использовать простое утверждение типа с переключателем типа, но невозможно управлять им на большом количестве структур case.

Следующий шаг, когда мы узнаем, что находится внутри интерфейса {} (я знаю, что не проверяю, является ли это структурой), мы можем пройти через это. Тип Reflect.Value имеет метод, который мы можем использовать для получения поля по индексу (есть также другая функция для получения поля по имени, но она мне не подошла). После того, как я получил поле, я хотел определить тип поля, потому что у каждого типа есть вспомогательная функция, проверяющая, содержит ли данное поле значение или нет.

Вспомогательные функции получают два параметра: первый относится к заданному типу поля и значению поля, второй также является интерфейсом {}, потому что второй параметр все еще неизвестен. Во вспомогательных функциях есть переключатели типа с типом, который нужно проверить. Вернуть логическое значение, указывающее, что поле содержит значение или нет.

Я попытался охватить все возможные типы данных, которые есть в Go, но еще не закончил.

Конец истории

Это базовая реализация для использования пакета отражения, однако она также решает мою проблему с помощью действительно хорошего времени тестирования, которое вы можете найти в readme библиотеки, но я чувствую, что это может быть лучше с некоторым рефакторингом и использованием Перейти к моделям параллелизма.

Возможности пакета отражения больше, и я попытаюсь записать, как я решил аналогичную проблему на сотнях проверок структур.