Интерфейсы в Go без боли
Интерфейсы в Go часто пугают новичков: — Где ключевое слово implements? — Как Go вообще понимает, что тип подходит? — Почему код компилируется, даже если я ничего не объявлял?
На самом деле интерфейсы в Go — одни из самых простых и мощных. Просто к ним нужно правильно подойти.
Интерфейс — это договор о поведении, а не о структуре. Например, ты заказываешь доставку. Тебе всё равно, кто приедет — курьер на машине, велосипеде или самокате. Важно только одно: он умеет доставлять.
type Courier interface {
Deliver(address string) error
}
Не важно, кто именно курьер. Важно, что у него есть метод Deliver. Как Go понимает, что тип реализует интерфейс: в Go не нужно явно писать implements. Если тип имеет все методы интерфейса — он его реализует. Точка.
type BikeCourier struct{}
func (b BikeCourier) Deliver(address string) error {
return nil
}
BikeCourier автоматически реализует Courier.
Поэтому в Go говорят: «если выглядит как утка и крякает как утка — это утка». Это называется "утиная типизация".
Это круто потому что:
1️⃣ Слабая связность Код зависит от поведения, а не от конкретной реализации.
func SendOrder(c Courier) {
_ = c.Deliver("Ленина, 10")
}
Теперь SendOrder не волнует, какой это курьер.
2️⃣ Лёгкая подмена реализаций
type CarCourier struct{}
func (c CarCourier) Deliver(address string) error {
return nil
}
Работает без изменений кода. Добавил новый тип — и поехали.
3️⃣ Простое тестирование
type FakeCourier struct{}
func (f FakeCourier) Deliver(address string) error {
return nil
}
Никаких мок-фреймворков. Интерфейсы в Go делают тесты естественными.
❌ Частая ошибка новичков создавать интерфейсы «на будущее»
type UserService interface {
Create()
Update()
Delete()
}
Если у тебя одна реализация — интерфейс не нужен.
✔️ Правило Go: интерфейсы должны возникать из потребности, а не из абстрактного дизайна. Маленькие интерфейсы — большое счастье.
В Go любят узкие интерфейсы:
type Reader interface {
Read(p []byte) (n int, err error)
}
Один метод — максимум гибкости. Поэтому стандартная библиотека так хорошо компонуется.
🖥 Когда точно стоит использовать интерфейсы:
- на границе модулей
- для работы с внешними зависимостями
- для тестов
- когда есть несколько реализаций одного поведения
Интерфейсы в Go: не про наследование и иерархии, а про поведение и простоту.
Если перестать думать «что это за тип» и начать думать «что он умеет», то Go станет в разы понятнее.
Взято с telegram-канала "Максим Аверин о Golang".
Комментарии
0
Ты: ...
Пока нет комментариев. Будь первым.