Указатель на структуру

Указатель на структуру в Go позволяет работать с экземпляром структуры через его адрес в памяти. При обращении к полям структуры через указатель, Go автоматически разыменовывает указатель, поэтому можно использовать синтаксис ptr.Field вместо (*ptr).Field. В первом параметре мы передаем указатель на структуру, во втором - значение поля, которое нужно изменить.

Синтаксис

govar ptr *StructName
ptr = &StructName{Field1: value1, Field2: value2}
value := ptr.Field1
ptr.Field2 = newValue

Пример

Давайте создадим указатель на структуру и обратимся к ее полям:

gopackage main

import "fmt"

type Person struct {
  Name string
  Age  int
}

func main() {
  p := &Person{Name: "Alice", Age: 30}
  fmt.Println(p.Name)
  fmt.Println(p.Age)
}

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

go"Alice"
30

Пример

Давайте изменим значение поля структуры через указатель:

gopackage main

import "fmt"

type Person struct {
  Name string
  Age  int
}

func main() {
  p := &Person{Name: "Bob", Age: 25}
  fmt.Println("Before:", p.Name, p.Age)
  p.Name = "Robert"
  p.Age = 26
  fmt.Println("After:", p.Name, p.Age)
}

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

go"Before: Bob 25"
"After: Robert 26"

Пример

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

gopackage main

import "fmt"

type Person struct {
  Name string
  Age  int
}

func updatePerson(p *Person, name string, age int) {
  p.Name = name
  p.Age = age
}

func main() {
  p := &Person{Name: "Charlie", Age: 35}
  fmt.Println("Before:", p.Name, p.Age)
  updatePerson(p, "Charles", 36)
  fmt.Println("After:", p.Name, p.Age)
}

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

go"Before: Charlie 35"
"After: Charles 36"

Пример

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

gopackage main

import "fmt"

type Person struct {
  Name string
  Age  int
}

func modifyCopy(p Person) {
  p.Name = "Copied"
  p.Age = 99
}

func modifyPtr(p *Person) {
  p.Name = "Pointer"
  p.Age = 99
}

func main() {
  p1 := Person{Name: "John", Age: 40}
  p2 := &Person{Name: "John", Age: 40}
  
  modifyCopy(p1)
  modifyPtr(p2)
  
  fmt.Println("After copy:", p1.Name, p1.Age)
  fmt.Println("After pointer:", p2.Name, p2.Age)
}

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

go"After copy: John 40"
"After pointer: Pointer 99"

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

  • информацию о структурах struct,
    которая описывает основы создания и использования структур
  • описание полей структуры fields,
    которое рассказывает о типах и именах полей
  • доступ к полям структуры field-access,
    который описывает чтение и запись полей
  • методы с получателем-указателем pointer-receiver,
    которые позволяют изменять состояние структуры