Go Academy · Урок

new() и когда использовать указатели

Выделение памяти с помощью new и распространённые шаблоны работы с указателями

Урок 4 из 413 шагов

«new() и когда использовать указатели» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Встроенная функция new()

new(T) выделяет обнулённое значение типа T и возвращает *T. Для структур это эквивалентно &T{}:

package main
import "fmt"

func main() {
    p := new(int)
    fmt.Println(*p)     // 0
    *p = 42
    fmt.Println(*p)     // 42

    type Point struct{ X, Y int }
    pt := new(Point)
    fmt.Println(*pt)    // {0 0}
}

new и &T{}

Для структур форма &T{} более идиоматична и позволяет инициализировать поля. В современном Go функция new используется редко:

package main
import "fmt"

type Config struct{ Port int; Host string }

func main() {
    a := new(Config)          // zeroed
    b := &Config{Port: 8080}  // initialized
    fmt.Println(a, b)
}

Когда возвращать указатель

Возвращайте указатель из конструктора, если:

  • Структура хранит состояние, и вызывающие стороны должны совместно использовать один экземпляр
  • У структуры есть методы с получателями-указателями (это необходимо для соответствия интерфейсам)
  • Структура большая и её копирование затратно

Когда возвращать значение

Возвращайте значение, если:

  • Тип небольшой (содержит несколько полей)
  • Это неизменяемая конфигурация
  • Вы хотите явно показать, что вызывающие стороны получают независимые копии

Пример: time.Time возвращается по значению, несмотря на наличие множества методов.

Указатели в срезах и отображениях

Хранение указателей в коллекциях позволяет совместно изменять данные:

package main
import "fmt"

type User struct{ Name string; Score int }

func main() {
    users := []*User{{"Alice", 0}, {"Bob", 0}}
    users[0].Score = 100
    fmt.Println(users[0]) // &{Alice 100}
}

Указатель на примитивный тип для обозначения необязательности

Поле типа *int или *string может иметь нулевое значение, означающее «не задано». Это полезно для JSON с параметром omitempty или необязательных столбцов базы данных:

package main
import "fmt"

type Profile struct {
    Name string
    Age  *int // nil means not provided
}

func main() {
    p := Profile{Name: "Alice"}
    fmt.Println(p.Age == nil) // true
    age := 30
    p.Age = &age
    fmt.Println(*p.Age) // 30
}

Как избежать чрезмерного использования указателей

Чрезмерное использование указателей увеличивает нагрузку на сборщик мусора и снижает локальность кэша. Прежде чем заменять типы-значения указателями только ради производительности, выполните сравнительный тест.

make и new

make инициализирует срезы, отображения и каналы (им требуется внутренняя настройка). new выделяет обнулённую память для любого типа и возвращает указатель. Эти функции предназначены для разных задач:

package main
import "fmt"

func main() {
    s := make([]int, 5)           // usable slice
    m := make(map[string]int)     // usable map
    p := new(int)                 // *int pointing to 0
    fmt.Println(s, m, *p)
}

Шаблон неизменяемого указателя

Возвращайте *T, но документируйте его как неизменяемый: потребители не должны его изменять. Это распространённый подход для объектов конфигурации, совместно используемых горутинами.

Итоги по безопасности указателей

Правила безопасной работы с указателями:

  • Всегда проверяйте нулевое значение перед разыменованием
  • Не храните указатели на переменные стека дольше времени жизни переменной (анализ выхода переменных за пределы области видимости в Go обрабатывает это)
  • Никогда не преобразуйте unsafe.Pointer без крайней необходимости
  • Позвольте компилятору управлять размещением в стеке и куче

Быстрая проверка

Что возвращает new(int)?

Итоги: new и указатели

Главные выводы:

  • new(T) возвращает обнулённый *T и используется редко; предпочитайте &T{}
  • Возвращайте значения для небольших и неизменяемых объектов, а указатели — для объектов с состоянием и больших объектов
  • Поля типа *T позволяют использовать нулевое значение как признак отсутствия
  • Не злоупотребляйте указателями — сборка мусора имеет свою цену

Практическое задание

Создайте структуру Settings с полем типа *int для MaxConnections. Напишите функцию, принимающую *Settings и устанавливающую значение по умолчанию только тогда, когда поле имеет нулевое значение.

Можно начать бесплатно

Изучай Go с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
51
Уроки
203

Часто задаваемые вопросы

Урок «new() и когда использовать указатели» бесплатный?

Да — полный текст урока «new() и когда использовать указатели» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «new() и когда использовать указатели»?

Выделение памяти с помощью new и распространённые шаблоны работы с указателями Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «new() и когда использовать указатели»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Что такое указатели
  2. Указатели и функции
  3. Получатели-указатели в методах
  4. new() и когда использовать указатели
← Назад к Go Academy