Значение или адрес
При вызове функции 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.
Указатель не делает все данные автоматически общими и не отменяет копирование: если функция принимает срез или карту, копируется само значение среза или карты, которое уже ссылается на общие данные.