Ответ
В Go функциональность, привязанная к определенному типу (например, к структуре), реализуется с помощью методов. Метод — это функция со специальным аргументом, называемым получателем (receiver), который указывается перед именем функции.
Получатель связывает функцию с типом. Он может быть двух видов: по значению или по указателю.
import "fmt"
type Rectangle struct {
Width, Height float64
}
// Метод с получателем по значению (value receiver)
// Работает с копией структуры. Не может изменять исходный объект `r`.
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// Метод с получателем по указателю (pointer receiver)
// Работает с оригиналом структуры через указатель. Может изменять исходный объект `r`.
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
Когда какой получатель выбирать?
*Используйте получатель-указатель (`T`), если:**
- Метод должен изменять состояние исходного объекта.
- Структура имеет большой размер. Передача указателя намного эффективнее, чем копирование всей структуры.
Используйте получатель-значение (
T
), если:- Метод не должен изменять состояние объекта (например, методы для вычислений или форматирования).
- Структура маленькая (например, базовые типы,
time.Time
) и ее копирование не несет больших накладных расходов. - Нужно гарантировать, что метод не изменит исходное значение (безопасность для конкурентного выполнения).
Важное замечание: Go предоставляет синтаксический сахар. Вы можете вызывать метод с указателем на переменной-значении (rect.Scale(2)
) и наоборот. Компилятор автоматически преобразует rect
в &rect
(и наоборот), если это необходимо.