Pointer receiver

Pointer receiver (получатель-указатель) в Go позволяет методу изменять исходную структуру, так как метод получает указатель на экземпляр структуры. При использовании указателя в качестве получателя, внутри метода мы работаем с оригинальной структурой, а не с ее копией. Это особенно полезно, когда метод должен модифицировать поля структуры.

Синтаксис

gofunc (s *StructType) MethodName(params) returnType {
  // тело метода
}

В синтаксисе метода с указателем в качестве получателя перед именем метода указывается переменная получателя со звездочкой *StructType. Это означает, что метод получает указатель на структуру и может изменять ее поля.

Пример изменения полей структуры

Давайте создадим структуру Person с методом UpdateName, который изменяет имя с помощью указателя:

gopackage main

import "fmt"

type Person struct {
  Name string
  Age  int
}

func (p *Person) UpdateName(newName string) {
  p.Name = newName
}

func main() {
  person := Person{Name: "John", Age: 30}
  person.UpdateName("Alice")
  fmt.Println(person.Name)
}

Результат выполнения кода:

go"Alice"

Метод UpdateName получает указатель на структуру Person, поэтому изменение поля Name отражается на исходной переменной.

Пример со значением по умолчанию

Давайте добавим метод SetDefaultAge, который устанавливает возраст по умолчанию, если он не указан:

gopackage main

import "fmt"

type Person struct {
  Name string
  Age  int
}

func (p *Person) SetDefaultAge() {
  if p.Age == 0 {
    p.Age = 18
  }
}

func main() {
  person := Person{Name: "Bob"}
  person.SetDefaultAge()
  fmt.Println(person.Age)
}

Результат выполнения кода:

go18

Метод SetDefaultAge изменяет поле Age, если оно равно нулевому значению. Благодаря указателю изменения сохраняются в исходной структуре.

Пример возврата измененной структуры

Метод с указателем может не только изменять поля, но и возвращать модифицированную структуру. Рассмотрим метод IncrementAge, который увеличивает возраст на заданное значение:

gopackage main

import "fmt"

type Person struct {
  Name string
  Age  int
}

func (p *Person) IncrementAge(years int) Person {
  p.Age += years
  return *p
}

func main() {
  person := Person{Name: "Charlie", Age: 25}
  updated := person.IncrementAge(5)
  fmt.Println(updated.Age)
}

Результат выполнения кода:

go30

Метод IncrementAge изменяет исходную структуру и возвращает ее копию. Это удобно, когда нужно и изменить, и получить результат.

Смотрите также