Назад к вопросам
Middle+
346
questionbank
Каково внутреннее устройство интерфейсов в Go?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Интерфейс в Go — это пара: указатель на данные и указатель на таблицу методов.
// Условная структура интерфейса (не существует в явном виде в коде Go)
type iface struct {
data uintptr // Указатель на значение
itab *itab // Указатель на таблицу типов и методов
}
// Условная структура таблицы методов (тоже не существует в явном виде)
type itab struct {
inter *interfaceType // Указатель на тип интерфейса
typ *_type // Указатель на конкретный тип, реализующий интерфейс
hash uint32 // Хеш для ускорения поиска
_ [4]byte // Выравнивание
fun [1]uintptr // Массив указателей на методы. Реальный размер зависит от количества методов.
}
data: Хранит указатель на фактическое значение, которое реализует интерфейс. Если значение по типу является указателем, тоdataуказывает на сам указатель. Если значение по типу не является указателем (например,int,string), оно может быть скопировано или храниться в отдельной структуре, на которую и указываетdata. Маленькие значения могут храниться непосредственно вdata.itab: Указатель на таблицу методов для конкретной пары интерфейс/тип. Эта таблица создается при первом преобразовании конкретного типа к этому интерфейсу или при компиляции для известных пар тип/интерфейс.
Когда вызывается метод интерфейса, Go использует itab, чтобы найти правильную функцию (метод) для вызванного типа и вызывает ее, передавая data как получателя.
Ключевые моменты:
- Go не требует явного объявления о реализации интерфейса. Проверка происходит в рантайме или статически в момент компиляции.
itabкэшируется, что ускоряет последующие вызовы методов того же интерфейса для того же типа.- Интерфейсы в Go "тонкие" (non-fat pointers) по сравнению с их аналогами в некоторых других языках, что способствует производительности.
- Пустой интерфейс (
interface{}) имеетitab, равный nil, поскольку у него нет методов, только указатель на данные (data).