package main
import "fmt"
func main() {
// Обычная переменная
message := "Hello, World!"
// Создаём указатель на переменную message
var ptr *string
ptr = &message
fmt.Println("Значение:", message) // Hello, World!
fmt.Println("Адрес:", &message) // 0x... (адрес в памяти)
fmt.Println("Указатель:", ptr) // 0x... (тот же адрес)
fmt.Println("Значение по указателю:", *ptr) // Hello, World!
} package main
import "fmt"
// Большая структура (представьте, что здесь много полей)
type User struct {
ID int
Name string
Email string
// ... ещё 20 полей
}
// Функция без указателя (копирует всю структуру)
func updateUserCopy(user User) {
user.Name = "Updated Name"
}
// Функция с указателем (работает с оригиналом)
func updateUserPtr(user *User) {
user.Name = "Updated Name"
}
func main() {
user := User{ID: 1, Name: "Original Name", Email: "user@example.com"}
fmt.Println("До вызова:", user.Name) // Original Name
updateUserCopy(user)
fmt.Println("После updateUserCopy:", user.Name) // Original Name (не изменилось)
updateUserPtr(&user)
fmt.Println("После updateUserPtr:", user.Name) // Updated Name (изменилось)
} // Способ 1: с ключевым словом var
var ptr *int
// Способ 2: с помощью new() (выделяет память и возвращает указатель)
ptr2 := new(int)
// Способ 3: взятие адреса существующей переменной
x := 42
ptr3 := &x package main
import "fmt"
func main() {
var ptr *int // ptr == nil (нулевой указатель)
fmt.Println(ptr) // <nil>
// ❌ Это вызовет панику!
// fmt.Println(*ptr)
// ✅ Правильно: сначала проверяем на nil
if ptr != nil {
fmt.Println(*ptr)
} else {
fmt.Println("Указатель равен nil, нельзя разыменовать")
}
// Присваиваем адрес
x := 42
ptr = &x
fmt.Println(*ptr)
} package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
// Создаём структуру
p := Person{Name: "Alice", Age: 30}
// Создаём указатель на структуру
ptr := &p
// Два способа доступа к полям через указатель:
fmt.Println((*ptr).Name) // Классический способ со скобками
fmt.Println(ptr.Name) // Go позволяет опускать * и скобки (синтаксический сахар)
// Изменение полей через указатель
ptr.Age = 31
fmt.Println(p.Age) // 31 (оригинальная структура изменилась)
}
package main
import "fmt"
func demonstrateLifetime() {
// Создаём данные в куче (heap)
data := make([]int, 1000)
data[0] = 42
// Создаём указатель на данные
ptr := &data[0]
fmt.Println(*ptr) // 42
// Даже когда функция завершится, данные останутся в памяти,
// если на них есть указатели из других мест
}
func main() {
var globalPtr *int
func() {
// Локальная переменная
local := 123
globalPtr = &local // ← Указатель сохраняется глобально
fmt.Println(*globalPtr) // 123
}()
// local больше не существует в области видимости,
// но данные не будут удалены, пока globalPtr на них указывает
fmt.Println(*globalPtr) // 123
// Только когда globalPtr перестанет указывать на эти данные,
// сборщик мусора сможет их удалить
globalPtr = nil
// Теперь сборщик мусора может очистить память
}