Как создать литерал *int64 в Go? Прямая инициализация указателя на число
Проблема: Почему нельзя взять адрес от литерала?
В Go вы не можете взять адрес от литерала (например, &123), потому что литералы не имеют адреса в памяти — они существуют только на этапе компиляции. Компилятор Go запрещает это для безопасности и предсказуемости.
Однако есть несколько простых и элегантных способов создать указатель на int64 без объявления отдельной переменной.
Способ 1: Вспомогательная функция (рекомендуется)
Самый популярный и читаемый способ — написать небольшую вспомогательную функцию:
func Int64Ptr(v int64) *int64 {
return &v
}
// Использование:
SetValue(Int64Ptr(123))
Эта функция принимает значение int64 и возвращает указатель на него. Параметр v является копией, которая живёт в стеке, и мы можем безопасно взять её адрес. В Go 1.22+ компилятор оптимизирует такие вызовы, и аллокации в куче не будет.
Способ 2: Использование переменной в одной строке
Можно объявить переменную и сразу взять её адрес:
val := int64(123)
SetValue(&val)
Это два оператора, но выглядит компактно. Если вы используете такой паттерн часто, лучше вынести в функцию.
Способ 3: Анонимная переменная (Go 1.22+)
Начиная с Go 1.22, можно использовать короткое объявление с _ (пустой идентификатор) для создания временной переменной:
SetValue(func() *int64 { v := int64(123); return &v }())
Но это избыточно — проще использовать вспомогательную функцию.
Способ 4: Пакет github.com/samber/lo (для проектов с зависимостями)
Если вы используете популярный пакет lo (Lodash-style библиотека), там есть готовые функции:
import "github.com/samber/lo"
SetValue(lo.ToPtr(int64(123)))
lo.ToPtr — это та же самая вспомогательная функция, но уже реализованная для всех типов.
Что выбрать новичку?
- Если это единичный случай — используйте Способ 2 (переменная + адрес).
- Если таких вызовов много в коде — напишите свою функцию-хелпер (Способ 1).
- Если проект уже использует
lo— беритеlo.ToPtr.
Важно: не пытайтесь городить сложные конструкции с new(int64) и присваиванием — это менее читаемо:
p := new(int64)
*p = 123
SetValue(p) // Работает, но много кода
В Go ценится простота и читаемость. Вспомогательная функция — это идиоматичный способ.
<<Альтернативный подход: Использование new() и присваивания
Можно использовать встроенную функцию new(), которая выделяет память под тип и возвращает указатель. Но есть нюанс: new(int64) возвращает указатель на нулевое значение (0). Поэтому нужно отдельно присвоить нужное значение:
p := new(int64) // *int64, указывает на 0
*p = 123 // Присваиваем нужное значение
SetValue(p)
Этот способ работает, но он многословен. Если вы используете его часто, лучше обернуть в функцию:
func Ptr[T any](v T) *T {
return &v
}
// Дженерик-версия для любого типа:
SetValue(Ptr(int64(123)))
Дженерики (Go 1.18+) позволяют создать одну универсальную функцию для всех типов. Это самый гибкий вариант, если вы работаете с разными типами указателей.
Минус: new() в некоторых случаях может вызывать аллокацию в куче, в отличие от вспомогательной функции с локальной переменной, которая может быть оптимизирована компилятором.
Ответов пока нет.
Войдите чтобы оставить ответ