Структура

Тип данных struct в Go позволяет объединять несколько значений разных типов в одну составную сущность. struct представляет собой коллекцию полей, где каждое поле имеет имя и тип данных. Структура определяется с помощью ключевого слова type и указания имени структуры, а затем объявления полей с указанием имени и типа данных каждого поля:

Person struct {
    Name string
    Age  int
    City string
}

Для создания экземпляра структуры используется оператор var вместе с именем структуры и фигурными скобками для инициализации полей:

var person Person
person.Name = "John"
person.Age = 30
person.City = "New York"
  1. Доступ к полям структуры: Доступ к полям структуры осуществляется с использованием оператора .. Например, person.Name обратится к полю Name в структуре person.
  2. Вложенные структуры: Структуры могут быть вложенными, что позволяет создавать более сложные структуры данных. Пример:
type Address struct {
    Street string
    City   string
}

type Person struct {
    Name    string
    Age     int
    Address Address
}

Struct embedding

Структурное встраивание (struct embedding) в Go позволяет включать одну структуру в другую без явного объявления полей. Это создает отношение "является" (is-a) между структурами, где встроенная структура получает доступ к полям и методам внешней структуры.

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

type Person struct {
    Name string
    Age  int
}

type Employee struct {
    Person
    EmployeeID int
}

Наследование полей и методов: В результате встраивания структуры Person в структуру Employee, поля и методы структуры Person автоматически становятся доступными в структуре Employee. Например, поле Name структуры Person может быть обращено как Employee.Name в структуре Employee.

Если структуры, встраиваемые в одну структуру, содержат поле с одинаковым именем, то необходимо указать имя структуры перед полем для разрешения неоднозначности. Например:

type Person struct {
    Name string
    Age  int
}

type Employee struct {
    Person
    Name       string
    EmployeeID int
}

В данном примере поле Name из структуры Person может быть обращено как Employee.Person.Name для различения от поля Name в самой структуре Employee.

Если во встроенной структуре имеется поле или метод с тем же именем, что и внешней структуре, то поле или метод внешней структуры будет переопределен. Переопределенное поле или метод будет доступно только через явное указание имени внешней структуры. Например:

type Person struct {
    Name string
    Age  int
}

func (p Person) Greet() {
    fmt.Println("Hello, I'm", p.Name)
}

type Employee struct {
    Person
    Name       string
    EmployeeID int
}

func (e Employee) Greet() {
    fmt.Println("Hello, I'm", e.Person.Name, "and I'm an employee")
}

В данном примере метод Greet() структуры Employee переопределяет метод с тем же именем в структуре Person.