Что такое обычный int и какие есть нюансы его реализации?go-24

Что такое обычный int?

В Go int — это базовый знаковый целочисленный тип, размер которого зависит от архитектуры целевой платформы:

var x int = 42  // Размер зависит от платформы

Ключевые характеристики

1. Платформозависимый размер

  • 32-битные системы: 32 бита (аналогичен int32)
  • 64-битные системы: 64 бита (аналогичен int64)

Проверка размера:

fmt.Println("Размер int в байтах:", unsafe.Sizeof(int(0)))

2. Диапазон значений

  • 32-бит: от -2,147,483,648 до 2,147,483,647
  • 64-бит: от -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807

Граничные константы:

math.MinInt  // Минимальное значение
math.MaxInt  // Максимальное значение

Нюансы реализации

1. Выбор размера компилятором

Размер int определяется:

  • Архитектурой целевой ОС (GOOS)
  • Разрядностью процессора (GOARCH)

Пример кросс-компиляции:

GOOS=linux GOARCH=386 go build  # 32-битный int
GOOS=linux GOARCH=amd64 go build  # 64-битный int

2. Производительность

  • На 64-битных платформах 64-битный int обычно работает быстрее
  • На 32-битных платформах 64-битные операции требуют двух инструкций

3. Совместимость с другими типами

Проблемы:

var a int = 42
var b int32 = 32
sum := a + b  // Ошибка: несовместимые типы

Решение:

sum := a + int(b)  // Явное приведение

4. Сериализация данных

При сериализации (JSON, protobuf и т.д.) int может вести себя по-разному:

  • В JSON всегда сериализуется как число
  • В бинарных форматах зависит от размера

5. Переполнение

Поведение при переполнении:

x := math.MaxInt
x++  // Станет math.MinInt (заворачивание)

Особые случаи использования

1. Индексы и длина

int используется для:

  • Индексов массивов/срезов
  • Возвращаемого значения len() и cap()
  • Параметров make()

Важно: Даже когда логичнее использовать uint, в Go предпочитают int

2. Системные вызовы

Во многих системных вызовах (например, unsafe.Sizeof) возвращается int

3. Циклы

for i := 0; i < n; i++ {  // i будет int
    // ...
}

Оптимизации компилятора

  1. Константная свертка: операции с константами вычисляются на этапе компиляции
  2. Регистровая аллокация: int часто остается в регистрах процессора
  3. Bounds check elimination: проверки границ могут удаляться для int индексов

Резюмируем

  1. int — знаковый целочисленный тип с платформозависимым размером
  2. Размер определяется целевой архитектурой (32 или 64 бита)
  3. Идиоматичен для индексов, длин и большинства целочисленных операций
  4. Требует явного приведения при работе с int32/int64
  5. При переполнении происходит "заворачивание"
  6. Оптимизирован компилятором для производительности
  7. Предпочтителен над uint в большинстве случаев согласно Go-идиоматике

Правила использования:

  • По умолчанию выбирайте int для целых чисел
  • Для явного контроля размера используйте int32/int64
  • Избегайте смешивания с uint без явного приведения
  • Учитывайте платформозависимость при сериализации данных