Методы указателей
При вызове метода объект структуры, для которого определен метод, передается в него по значению. Что это значит? Рассмотрим следующий пример.
Самое время протестировать код!
Для структуры person определен метод updateAge, который принимает параметр newAge и изменяет значение поля age у структуры. То есть при вызове этого метода мы ожидаем, что возраст человека изменится. Однако консольный вывод нам показывает, что значение поля age не изменяется.
Так происходит, потому что при вызове tom.updateAge(33) метод updateAge получает копию структуры tom. То есть структура tom копируется в другой участок памяти, и далее метод updateAge работает с копией, никак не затрагивая оригинальную структуру tom.
Однако такое поведение может быть нежелательным. Что, если мы все-таки хотим таким образом изменять состояние структуры? В этом случае необходимо использовать указатели на структуры.
Самое время протестировать код!
Теперь метод updateAge принимает указатель на структуру person: p *person, то есть фактически — адрес структуры в памяти. С помощью операции разыменования получаем значение по этому адресу в памяти и меняем поле age.
В функции main определяем указатель на структуру person и передаем ему адрес структуры tom.
Затем вызываем метод updateAge.
Таким образом, метод updateAge получит адрес, который хранится в tomPointer и по этому адресу обратится к структуре tom, изменив значение ее свойства age.
Несмотря на то, что метод updateAge определен для указателя на структуру person, мы по-прежнему можем вызывать этот метод и для объекта person.
Помни: методы являются синтаксическим сахаром в языке, ресивер является первым параметром в функции.
Внимание! Все ссылки просматриваются сборщиком мусора (garbage collector — сокращенно GC или gc), а значит большое количество ссылок увеличивает нагрузку на gc, то есть и на само приложение. Если объект не меняет значений, объект временный, без персистенса, используйте методы по значению вроде вызова статических функций в php.
Если хоть один ресивер является ссылкой, у всех методов ресивер должен быть ссылкой и наоборот (viceversa).
Рекомендуем также ознакомиться с дополнительными материалами по теме:
-
«Изучаем Golang. Урок №12. Методы» [целиком];
-
«Methods».