Сравнение структур и интерфейсов в Go: в чем их сходства и различия?

Ответ

В Go отсутствуют классы в их классическом понимании. Вместо них для создания собственных типов данных и определения поведения используются структуры (struct) и интерфейсы (interface).

Структуры (struct) — это композитные типы данных, которые объединяют поля (данные) в единое целое. Они являются конкретными типами.

Интерфейсы (interface) — это абстрактные типы, которые определяют набор методов (контракт). Любой тип, реализующий все методы интерфейса, неявно удовлетворяет этому интерфейсу.

Ключевые различия:

  • Данные vs. Поведение: Структуры содержат данные (поля), а интерфейсы определяют поведение (методы).
  • Конкретность vs. Абстракция: Структура — это конкретная реализация, а интерфейс — это абстрактное определение контракта.
  • Реализация: Структуры реализуют интерфейсы. Интерфейсы не могут содержать поля или реализацию методов.
  • Нулевое значение: Нулевое значение для структуры — это экземпляр с нулевыми значениями для всех полей. Нулевое значение для интерфейса — nil.

Сходство:

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

Пример:

// Интерфейс определяет поведение "говорить"
_type_ Speaker _interface_ {
    Speak() string
}

// Структура Dog с полем Name
_type_ Dog _struct_ {
    Name string
}

// Dog реализует интерфейс Speaker
_func_ (d Dog) Speak() string {
    _return_ fmt.Sprintf("%s says Woof!", d.Name)
}

// Структура Cat с полем Name
_type_ Cat _struct_ {
    Name string
}

// Cat реализует интерфейс Speaker
_func_ (c Cat) Speak() string {
    _return_ fmt.Sprintf("%s says Meow!", c.Name)
}

_func_ main() {
    // Мы можем использовать разные типы через один интерфейс
    speakers := []Speaker{Dog{Name: "Rex"}, Cat{Name: "Murzik"}}
    _for_ _, s := _range_ speakers {
        fmt.Println(s.Speak())
    }
}