← Все этапы
03 · ДАННЫЕ И ТИПЫУрок 16 из 3322 минуты

Указатели и изменение данных

Передаём адрес значения и меняем исходную переменную через разыменование.

Значение или адрес

При вызове функции Go передаёт аргумент по значению: функция получает копию. Если передать число, присваивание копии не изменит переменную вызывающего кода. Указатель — значение, содержащее адрес другого значения; с ним функция может обратиться к исходной переменной.

Указательный тип записывается как *int, а оператор & берёт адрес переменной. Оператор * перед переменной-указателем разыменовывает его — читает или меняет значение по адресу. Нулевое значение указателя — nil; разыменовывать nil нельзя.

Пример

package main

import "fmt"

func addBonus(points *int, bonus int) {
	*points += bonus
}

func main() {
	score := 40
	addBonus(&score, 7)
	fmt.Printf("счёт: %d\n", score)

	var next *int
	fmt.Printf("не задан следующий счёт: %t\n", next == nil)
}

В функцию передан адрес переменной score. Изменение *points обновляет то же значение, поэтому результат равен 47. Аргумент bonus остаётся обычной копией целого числа.

Указатель на структуру

Адрес структуры можно передать так же: функция принимает, например, *parcel и меняет поля исходной структуры. Для поля допустима короткая запись parcel.city даже при указателе: Go автоматически разыменовывает его в таком выражении. До обращения проверь, что указатель не равен nil.

Указатель не делает все данные автоматически общими и не отменяет копирование: если функция принимает срез или карту, копируется само значение среза или карты, которое уже ссылается на общие данные.

Практика

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

Напиши функцию applyDiscount(price *int, amount int), которая уменьшает цену через указатель. В main создай цену 1200, вызови функцию со скидкой 250 и напечатай цену. Затем объяви нулевой указатель на int и выведи, равен ли он nil, не разыменовывая его.

Проверка результата

Как понять, что получилось

После вызова цена равна 950, а проверка указателя печатает true. Функция меняет значение через *price; вызов передаёт &cost.

Указатели и изменение данных | Go | WebSchool · Go