Перейти к содержанию

Структуры и методы

Структура (struct) — это пользовательский тип с набором полей. Если переменных, которые «принадлежат друг другу», много — собирай их в структуру. Метод — это функция, привязанная к типу.

Что должен понять

  • Как объявить структуру и создать её экземпляр.
  • В чём разница между value receiver и pointer receiver.
  • Зачем нужен конструктор-функция NewX().
  • Что нулевая структура — это валидная структура с zero-полями.

Объявление и создание

type User struct {
    Name string
    Age  int
}

func main() {
    u := User{Name: "Anna", Age: 25}
    fmt.Println(u.Name, u.Age)

    var v User                  // zero-struct: "", 0
    v.Name = "Boris"
    fmt.Println(v)
}

Поля с большой буквы — публичные (видны из других пакетов). С маленькой — приватные.

Методы: value receiver

type Rectangle struct {
    W, H float64
}

func (r Rectangle) Area() float64 {
    return r.W * r.H
}

r := Rectangle{W: 3, H: 4}
fmt.Println(r.Area())   // 12

Внутри метода r — это копия. Изменение r.W = 99 не повлияет на оригинал.

Методы: pointer receiver

func (r *Rectangle) Scale(k float64) {
    r.W *= k
    r.H *= k
}

r := Rectangle{W: 3, H: 4}
r.Scale(2)
fmt.Println(r)   // {6 8}

Используй pointer receiver, когда:

  • Нужно изменить поля.
  • Структура большая и копирование дорого.
  • Хочешь, чтобы все методы типа были одного «вида» (это считается стилем).

Конструктор NewX

В Go нет ключевого слова new в смысле Java. Стандартный паттерн — функция NewType:

func NewUser(name string, age int) *User {
    return &User{
        Name: name,
        Age:  age,
    }
}

u := NewUser("Anna", 25)
fmt.Println(u.Name)

Когда использовать:

  • Нужна валидация при создании.
  • Нужно установить значения по умолчанию.
  • Нужно вернуть указатель готового объекта.

Если структура простая и валидации нет — литерала достаточно.

Типичные ошибки

  • Объявили метод с value receiver и удивляются, что изменения не видны.
  • Смешали value и pointer receiver у одного типа без причины.
  • Сделали все поля приватными, потом не могут их прочитать в тестах.

Критерии приёмки модуля

  • Объявлена структура Rectangle с методами Area() и Scale(k).
  • В одном методе value receiver, в другом pointer receiver.
  • Реализован конструктор NewRectangle(w, h float64) *Rectangle.
  • Программа выводит площадь до и после Scale.

Дальше: Мини-проекты.