Интерфейсы в Go: как работает полиморфизм

Мы просто и по делу рассказываем про ИИ-инструменты для работы: сравнения, пошаговые гайды, бесплатные альтернативы и реальные сценарии применения. Помогаем выбрать между ChatGPT, Gemini, Claude, локальными моделями и десятками узкоспециализированных сервисов — от дизайна и HR до аналитики и SEO. Меньше хайпа, больше практики и экономии времени каждый день.

goинтерфейсыполиморфизм

В Go полиморфизм строится не на наследовании, а на интерфейсах. Это один из ключевых принципов языка: код зависит не от конкретной реализации, а от поведения.

Что такое интерфейс в Go

Интерфейс — это набор методов. Если тип реализует все методы интерфейса, он автоматически считается его реализацией. Явно писать implements не нужно.

type Speaker interface {
    Speak() string
}

type Dog struct{}
func (d Dog) Speak() string { return "Woof" }

type Cat struct{}
func (c Cat) Speak() string { return "Meow" }

И Dog, и Cat подходят под Speaker, потому что у них есть метод Speak().

Как здесь работает полиморфизм

Полиморфизм — это возможность работать с разными типами через один общий интерфейс.

func SaySomething(s Speaker) {
    fmt.Println(s.Speak())
}

Теперь функция SaySomething не знает, кто именно передан: собака, кошка или любой другой тип. Главное — чтобы он умел Speak().

Это даёт:

  • гибкость архитектуры
  • слабую связанность кода
  • простую замену реализаций
  • удобное тестирование через моки 🧪

Почему это удобно в реальных проектах

Например, есть сервис отправки уведомлений:

type Notifier interface {
    Send(message string) error
}

Реализации могут быть разными:

  • EmailNotifier
  • TelegramNotifier
  • SMSNotifier

Основной код работает только с Notifier, а не с конкретным каналом доставки. Это упрощает масштабирование и поддержку проекта 🚀

Пустой интерфейс и any

Раньше для хранения значения любого типа использовали interface{}. Сейчас для этого есть алиас any.

func Print(value any) {
    fmt.Println(value)
}

Но применять any стоит осторожно: он снижает типобезопасность и часто делает код менее понятным.

Важный нюанс: interface и nil

Одна из частых ловушек в Go — интерфейс может быть не равен nil, даже если внутри лежит nil-указатель. Это происходит потому, что интерфейс хранит:

  • конкретный тип
  • конкретное значение

Если тип известен, интерфейс уже не считается nil ⚠️

Когда использовать интерфейсы

Интерфейсы полезны, если:

  • есть несколько реализаций одного поведения
  • нужен чистый и расширяемый API
  • важна подмена зависимостей в тестах
  • хочется уменьшить связанность между пакетами

Но не стоит создавать интерфейсы “на будущее”. В Go хорошая практика — объявлять интерфейс там, где он нужен потребителю, а не производителю.

Итог

Интерфейсы в Go — это основа полиморфизма без сложной иерархии классов. Они позволяют писать простой, гибкий и поддерживаемый код. Главное правило: описывайте не сущности, а действия, которые от них ожидаете 🔧

Подборку полезных каналов про IT — стоит посмотреть в закрепе/описании канала 📚

🗣 Подборки каналов
🧠 Каталог ботов и приложений
🗺 Навигация

Читайте так же