Go Academy · Урок

Анонимные структуры и композиция

Встраивание и повторное использование кода на основе структур

Урок 4 из 413 шагов

«Анонимные структуры и композиция» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Анонимные структуры

Анонимная структура не имеет именованного типа. Она определяется непосредственно в месте использования и полезна для краткоживущих данных, табличных тестов и разовых группировок:

package main
import "fmt"

func main() {
    point := struct{ X, Y int }{X: 3, Y: 7}
    fmt.Println(point.X, point.Y)
}

Анонимные структуры в табличных тестах

Распространённый идиоматичный приём Go — использовать срез анонимных структур для табличных тестов:

package main
import "fmt"

func double(n int) int { return n * 2 }

func main() {
    tests := []struct{ input, want int }{
        {1, 2}, {5, 10}, {0, 0},
    }
    for _, tt := range tests {
        got := double(tt.input)
        if got != tt.want {
            fmt.Printf("FAIL: double(%d) = %d, want %d\n", tt.input, got, tt.want)
        }
    }
    fmt.Println("all tests passed")
}

Встраивание структур

Встраивание типа в структуру делает его поля и методы доступными во внешней структуре:

package main
import "fmt"

type Animal struct{ Name string }
func (a Animal) Speak() string { return a.Name + " speaks" }

type Dog struct {
    Animal        // embedded
    Breed string
}

func main() {
    d := Dog{Animal: Animal{"Rex"}, Breed: "Labrador"}
    fmt.Println(d.Name)    // promoted field
    fmt.Println(d.Speak()) // promoted method
}

Множественное встраивание

Структура может встраивать несколько типов. Конфликты (одинаковые имена полей или методов) необходимо разрешать явно:

package main
import "fmt"

type Logger struct{}
func (Logger) Log(s string) { fmt.Println("[LOG]", s) }

type Metrics struct{}
func (Metrics) Count() int { return 42 }

type Service struct {
    Logger
    Metrics
    Name string
}

func main() {
    svc := Service{Name: "auth"}
    svc.Log("started")       // from Logger
    fmt.Println(svc.Count()) // from Metrics
}

Встраивание и наследование

В Go нет наследования классов. Встраивание — это композиция:

  • Встраивание делает поля и методы доступными, но внешний тип не становится подтипом
  • Нельзя передать Dog туда, где ожидается Animal
  • Используйте интерфейсы для полиморфизма, а встраивание — для повторного использования кода

Переопределение поднятых методов

Внешняя структура может скрыть встроенный метод, определив собственный:

package main
import "fmt"

type Base struct{}
func (Base) Hello() string { return "Base hello" }

type Child struct{ Base }
func (Child) Hello() string { return "Child hello" } // shadows Base.Hello

func main() {
    c := Child{}
    fmt.Println(c.Hello())      // Child hello
    fmt.Println(c.Base.Hello()) // Base hello (explicit)
}

Анонимная структура для конфигурации

Используйте анонимную структуру, чтобы объединить связанную конфигурацию без определения именованного типа:

package main
import "fmt"

func main() {
    cfg := struct {
        Host string
        Port int
        TLS  bool
    }{
        Host: "api.example.com",
        Port: 443,
        TLS:  true,
    }
    fmt.Println(cfg)
}

Встраивание интерфейса

Встраивание интерфейса в структуру удобно для создания имитаций и реализаций по умолчанию:

package main
import "fmt"

type Reader interface{ Read() string }

type Mock struct{ Reader }  // embed interface

func main() {
    m := Mock{}
    fmt.Printf("%T\n", m.Reader) // <nil> — not set
    // Assign a real impl at test time:
    _ = m
}

Подводные камни композиции структур

Обратите внимание на:

  • Неоднозначные селекторы, когда у двух встроенных типов совпадает имя поля или метода
  • Встроенный указатель nil, вызывающий панику при вызове его методов
  • Помните, что встраивание — это не наследование: внешний тип нельзя использовать вместо встроенного типа

Сравнение анонимных структур

Две анонимные структуры с одинаковыми именами и типами полей совместимы для присваивания друг другу, если их теги также совпадают:

package main
import "fmt"

func main() {
    a := struct{ X, Y int }{1, 2}
    b := struct{ X, Y int }{1, 2}
    fmt.Println(a == b) // true
}

Быстрая проверка

Что даёт встраивание типа в структуру?

Повторение: композиция

Основные выводы:

  • Анонимные структуры отлично подходят для табличных тестов и краткоживущих данных
  • Встраивание делает поля и методы доступными — это композиция, а не наследование
  • Внешние типы могут скрывать встроенные методы
  • Неоднозначные селекторы необходимо разрешать явно
  • Используйте интерфейсы для полиморфизма

Задание для практики

Создайте структуру TimestampedRecord, которая встраивает Timestamp struct{ CreatedAt, UpdatedAt string } и Data struct{ Key, Value string }. Создайте её экземпляр и выведите все поднятые поля.

Можно начать бесплатно

Изучай Go с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
51
Уроки
203

Часто задаваемые вопросы

Урок «Анонимные структуры и композиция» бесплатный?

Да — полный текст урока «Анонимные структуры и композиция» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «Анонимные структуры и композиция»?

Встраивание и повторное использование кода на основе структур Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Анонимные структуры и композиция»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Определение и использование структур
  2. Методы структур
  3. Шаблоны конструкторов
  4. Анонимные структуры и композиция
← Назад к Go Academy