Методы
Методы привязывают поведение к типу. Главный вопрос: получатель — значение или указатель?
Метод — это функция с особым параметром-получателем (receiver), который пишут перед именем метода. Он связывает функцию с типом.
Что такое метод
Метод — обычная функция, но с получателем в скобках до имени. Получатель указывает, к какому типу относится метод. Вызывают метод через точку.
package main
import "fmt"
type Rectangle struct {
Width, Height float64
}
// (r Rectangle) — получатель-значение
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func main() {
rect := Rectangle{Width: 3, Height: 4}
fmt.Println(rect.Area())
}Вывод:
12
Главный вопрос: value vs pointer receiver
Получатель бывает двух видов, и выбор между ними — ключевое решение.
- Получатель-значение
(r Rectangle)работает с копией. Изменения внутри метода не затрагивают оригинал. Подходит для методов, которые только читают. - Получатель-указатель
(r *Rectangle)работает с оригиналом. Может его менять. Нужен, когда метод изменяет состояние.
package main
import "fmt"
type Counter struct {
value int
}
// получатель-значение: меняет копию (бесполезно)
func (c Counter) IncBroken() { c.value++ }
// получатель-указатель: меняет оригинал
func (c *Counter) Inc() { c.value++ }
func main() {
c := Counter{}
c.IncBroken()
fmt.Println(c.value) // 0 — не изменилось
c.Inc()
c.Inc()
fmt.Println(c.value) // 2 — изменилось
}Вывод:
0 2
Здесь IncBroken увеличивает счётчик в копии, и оригинал остаётся нулём — классическая ошибка новичка. Inc с указателем работает правильно.
Удобство Go
Go автоматически берёт адрес при вызове метода с указателем: можно писать c.Inc(), а не (&c).Inc(). Компилятор подставит & сам, если переменная адресуема.
Какое правило выбрать
Практическое правило: если хотя бы один метод типа использует указатель — делайте указателями все методы этого типа для единообразия. Указатель также предпочтителен для больших структур (чтобы не копировать) и когда метод меняет состояние.
| Получатель | Когда использовать |
значение (r T) | метод только читает, тип маленький |
указатель (r *T) | метод меняет состояние или тип большой |
Итог
- Метод — функция с получателем перед именем; вызывается через точку.
- Получатель-значение меняет копию, получатель-указатель — оригинал.
- Меняете состояние или тип большой — берите указатель; держите получатели единообразными.