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

У каждого языка программирования есть своя собственная модель отражения, но каждая модель отражения построена на системе типов. Итак, прежде чем использовать рефлексию, очень важно иметь лучшее понимание системы типов языка программирования, с которым мы работаем (в данном контексте Go).

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

Иногда нам нужно (или необходимо) работать с переменными или фрагментами информации, которые неизвестны на момент написания программы. Это применимо, когда вы пишете программу, которая обрабатывает данные, полученные по сети, или программу, которая может работать с разными типами. В этих случаях вам нужно размышление.

отражать пакет

В контексте Go, если вы хотите использовать отражение, вам нужно использовать пакет отражения. Этот пакет реализует отражение времени выполнения в Go. Это помогает нам проверять типы, типы и значения переменных, над которыми мы работаем. Кроме того, он реализует набор методов, которые могут создавать новые экземпляры или изменять состояние существующих.

Краткое заявление об отказе от ответственности r: Способ реализации пакета отражения предполагает, что вы действительно знаете, что делаете при его использовании, поэтому многие методы и функции вызовут панику, если их не использовать должным образом.

Тип, вид, значение

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

Прежде всего я хочу упомянуть разницу между Типом и Типом. Возьмем следующий пример:

rType будет содержать тип переменной r. В нашем примере значением будет main.Rectangle, который является (типом, который мы определили) Reflection.Type на уровне абстракции, а типом будет struct. rValue будет фактическим значением переменной r.

Go - это статически типизированный язык программирования, поэтому rType, rKind и rValue должны иметь свои собственные типы. Пока мы можем идентифицировать связи:

  • Reflect.TypeOf принимает интерфейс в качестве параметра и возвращает отражение.Type
  • Отражение.ValueOf принимает интерфейс в качестве параметра и возвращает отражение.Значение
  • Kind - это метод, возвращающий отражение.

Тем не менее, есть существенная разница между отражением.Value и фактическим значением переменной. Итак, reflection.Value можно использовать только в контексте отражения. Чтобы преобразовать из Reflect.Value в фактическое общее используемое значение, нам нужно использовать метод Reflect.Value.Interface и привести результирующий интерфейс к желаемому типу.

Проверка переменных

Когда мы включаем в наблюдение переменную, имеющую структуру Kind, отражение предлагает вам подробную информацию о количестве полей в структуре и каждой структуре полей. Эту информацию можно найти в Reflect.StructField. Здесь вы можете найти информацию о названии поля, его типе и виде или список тегов.

Если переменная является фрагментом, каналом, указателем, картой или массивом, вы можете извлечь тип переменной, а после этого, используя vType.Elem (), вы можете узнать тип содержащихся элементов.

Бегите на площадку, чтобы проверить выход.

Изменение состояний или создание новых экземпляров

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

Чтобы изменить значение переменной с помощью отражения, вам понадобится указатель на значение. Получение указателя осуществляется с помощью addr: = reflection.ValueOf (& var). Чтобы установить новое значение переменной var, вы будете использовать addr.Elem (). Set (newValue), где newValue должно быть отражением.Value.

Чтобы создать новый экземпляр, вы будете использовать Reflect.New (type), где type должен быть отражением .Type. Отражение.New вернет указатель на значение, которое можно изменить с помощью Elem (). Set (), как описано в предыдущем абзаце.

Go не имеет универсальных шаблонов, и возвращение из рефлексии. Значение переменной общего использования немного противоречит здравому смыслу, поскольку исходный тип переменной теряется. Итак, чтобы вернуться, вам нужно использовать метод Interface (), который вернет переменную с типом interface {}, а для возврата к исходному типу потребуется преобразовать интерфейс к исходному типу. См. Пример ниже для более подробной информации или запустите пример в детской площадке.

Отражение и функции

Reflection дает возможность работать также с функциями. Используя Reflect.MakeFunc, вы можете создавать новые функции во время выполнения. Эта функция требует отражения. Тип для функции и закрытие с 2 [] рефлектом. Значение в качестве входных и выходных параметров.

Запустите пример на детской площадке.

Вместо заключения

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

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

Следует сказать о минусах. На мой взгляд, серьезным недостатком является то, что отражение может снизить безопасность и точность инструментов рефакторинга и анализа, поскольку они не могут определять информацию о типах и полагаться на нее.

Короче говоря, с большой силой приходит большая ответственность. Уделяйте много внимания использованию отражения и наслаждайтесь его гибкостью!