Взгляд на типы значений и ссылок и что они означают для указателей

Что такое указатель?

Указатель — это переменная, которая используется для хранения адреса памяти другой переменной.

Эта диаграмма, надеюсь, сделает это более понятным. Мы создали переменную с именем number, и эта переменная имеет как адрес, так и значение. Затем, если мы создадим указатель, равный &number, & даст нам адрес числа, тогда мы сможем использовать этот адрес, чтобы найти значение 50 и обновить его.

Итак, я думаю, теперь вопрос в том, почему мы не можем просто использовать нашу переменную и обновить значение как таковое.

В приведенном выше коде я создал простую структуру с именем user, которая имеет имя пользователя и возраст. Моя функция updateAge имеет приемник типа user, и все, что она делает, это устанавливает возраст этого пользователя на новый возраст, который мы прошли, в нашем случае 11. Однако это не сработает, и Println в строке 17 выведет пользователя в возрасте 10 лет. Так почему же? Причина в том, что Go — это язык передачи по значению или другими словами — он создает копию значения в функции.

Давайте подробнее рассмотрим, как это работает.

Поскольку Go — это язык передачи по значению, когда мы передаем значение в функцию, Go создает копию этого значения, а затем эта копия становится доступной для кода в функции. Вот почему в коде, который мы видели выше, когда мы печатаем 'john', его возраст не менялся, но если бы Println находился внутри func, после установки newAge мы бы' Мы видели, что возраст копии действительно был обновлен до нового значения.

Зная все это, мы теперь можем увидеть, как использовать указатель для решения этой маленькой проблемы.

Использование указателей

Для начала я вставлю рабочий код ниже, а затем пройдусь по изменениям.

Единственные изменения были сделаны в строке 16, где мы создали указатель, указывающий на адрес john с помощью символа '&'. А затем вместо вызова функции updateAge для john мы делаем это для указателя. Другое изменение заключается в том, что в нашей функции updateAge получатель теперь является указателем, а перед пользователем стоит символ '*'. Давайте визуализируем, что это делает.

Вот что означают эти 2 таинственных символа. А в func логика такая:

Когда нам нужны указатели?

Если мы пытаемся обновить какие-либо типы значений, то указатель обязательно понадобится, но если мы работаем со ссылочными типами, нам не нужно беспокоиться о точках.