Menu
Coddy logo textTech

Получатели-указатели и получатели-значения

Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy — урок 8 из 107.

Методы могут иметь либо получатель значения, либо получатель-указатель. Получатель значения работает с копией структуры. Получатель-указатель работает с оригинальной структурой и может изменять её поля.

Приемник значения — работает с копией

type Counter struct {
    Count int
}

func (c Counter) GetCount() int {
    return c.Count
}

// Это НЕ изменяет оригинал
func (c Counter) IncrementWrong() {
    c.Count++ // Изменяет только копию!
}

Указатель-получатель — изменяет оригинал

// Это ДЕЙСТВИТЕЛЬНО изменяет оригинал
func (c *Counter) Increment() {
    c.Count++
}

func (c *Counter) Reset() {
    c.Count = 0
}

Использование обоих вместе

func main() {
    counter := Counter{Count: 0}

    counter.Increment()
    counter.Increment()
    fmt.Println(counter.GetCount()) // Вывод: 2

    counter.Reset()
    fmt.Println(counter.GetCount()) // Вывод: 0
}

Используйте получатель значения, когда метод только считывает данные. Используйте указатель-получатель (*StructName), когда методу необходимо изменить поля структуры. Go автоматически обрабатывает получение указателя и разыменование — вы вызываете оба типа методов одинаково.

challenge icon

Задание

Средне

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

  • GetBalance — получатель по значению, возвращает текущий баланс
  • Deposit — получатель по указателю, добавляет сумму к балансу
  • Withdraw — получатель по указателю, вычитает сумму только при наличии достаточного количества средств

Шпаргалка

Методы могут иметь либо получатель значения, либо получатель-указатель. Получатель значения работает с копией структуры. Получатель-указатель работает с оригинальной структурой и может изменять её поля.

Получатель значения — работает с копией:

type Counter struct {
    Count int
}

func (c Counter) GetCount() int {
    return c.Count
}

Получатель-указатель — изменяет оригинал:

func (c *Counter) Increment() {
    c.Count++
}

Используйте получатель значения, когда метод только считывает данные. Используйте получатель-указатель (*StructName), когда методу необходимо изменить поля структуры.

Попробуйте сами

package main

import "fmt"

func main() {
    var balance, deposit, withdraw float64
    fmt.Scan(&balance, &deposit, &withdraw)

    w := Wallet{Balance: balance}

    fmt.Printf("Balance: %.2f\n", w.GetBalance())

    w.Deposit(deposit)
    fmt.Printf("After deposit: %.2f\n", w.GetBalance())

    w.Withdraw(withdraw)
    fmt.Printf("After withdrawal: %.2f\n", w.GetBalance())

    fmt.Printf("Final balance: %.2f\n", w.GetBalance())
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование