2016-01-05 2 views
5

Используя отражение, мы можем получить имя типа, размер хранилища и функцию данного типа (например, uint64, определяемая пользователем структура и т. Д.). Даже мы можем модифицировать некоторые поля данного типа. Как отражать голанг? Я думаю, одним из следующих способов:Как отражать отражение голанга?

  1. Каждый тип в golang, включая определяемый пользователем тип, сам по себе имеет информацию об имени типа, поля имя и имя функции. Отражение Голанга просто считывает эту информацию или вызывает функцию.

  2. Через какой-то механизм Golang может получить имя типа, размер хранилища и т. Д. И сам тип не имеет такой информации.

Я прочел код отражения голанга примерно. Я догадался, что голанг использовал второй путь. Кто может описать конкретный инструмент отражения? Или порекомендовать мне несколько документов? Чтение всего кода мне сложно.

+0

Проще говоря, как отражение голангов получает информацию типа, типа имени типа, размера хранилища, полей, функции и т. Д. Даже отражение может установить значение. –

ответ

4

Это просто обзор, и он может быть не на 100% точным, но, надеюсь, вы найдете его полезным.

во время сборки Перейти линкер будет вставлять информацию обо всех типов, используемых приложением в исполняемый файл (https://github.com/golang/go/blob/master/src/runtime/symtab.go#L39)

Каждое значение интерфейса содержит указатель на тип данных дескриптора (https://github.com/golang/go/blob/master/src/runtime/type.go#L14)

В процессе преобразования из тип, который известен во время компиляции для значения интерфейса Go, будет указывать дескриптор типа этого значения интерфейса на конкретный дескриптор типа (он известен во время компиляции!).

E.g. когда вы звоните reflect.TypeOf(uint(87)):

  • значением интерфейса создается компилятором, который ссылается uint тип дескриптора
  • это значение интерфейса передается reflect.TypeOf функции в качестве аргумента
  • reflect.TypeOf функция использует тип дескриптора, который хранился на компоновщик в исполняемом файле, чтобы получить выровненную (и другую) информацию о типе uint.
1

Описание интерфейсов хорошо описано здесь: The Laws of Reflection.

Переменная типа интерфейса хранит пару: конкретное значение , присвоенное переменной, и дескриптор этого значения.

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

+0

Например, https://play.golang.org/p/KGTz2WscGY Как механизм отражения получает информацию о выравнивании типа uint? –