Что лучше использовать в Go: int8, int32, int64 или просто int
Что проверяют
Знаете ли вы, что в Go выбор целочисленного типа это не микрооптимизация, а вопрос контракта. Заодно проверяют понимание платформозависимости int и того, как язык ведёт себя при переполнении и при смешивании типов.
Как отвечать
По умолчанию int. Это тип индексов и длин: len и cap возвращают именно его, и любое отклонение потребует явных преобразований по всему коду. Ширина у него зависит от платформы, на современных сборках это 64 бита.
Фиксированные размеры берут, когда размер становится частью договорённости:
- бинарные форматы, сетевые протоколы, записи на диск: там ширина поля задана спецификацией;
- взаимодействие с кодом на C и с системными вызовами;
- большие срезы однотипных чисел, где сужение типа действительно экономит память;
- внешний интерфейс, который обещает конкретный диапазон значений.
Стоит добавить два факта. Арифметика на узких типах не быстрее: процессор всё равно считает полными регистрами, а компилятору приходится усекать результат. И преобразования в Go всегда явные: сложить int32 с int64 без конверсии нельзя, компилятор не пропустит.
Где спотыкаются
Сужают типы в обычных структурах ради экономии. Выравнивание съедает выгоду: поле int8 рядом с int64 чаще всего всё равно займёт восемь байт, зато риск переполнения появится. Экономия работает на миллионах элементов в срезе, и там же важнее порядок полей.
Считают int синонимом int64 и пишут его в формат обмена. Ширина зависит от платформы, поэтому в протоколе и в файле указывают фиксированный тип. Отдельная ловушка: большое целое в JSON при разборе может попасть в число с плавающей точкой и потерять точность.
Забывают, что переполнение в Go тихое. Значение int8, равное 127, после прибавления единицы станет -128, без паники и предупреждения. Тот же класс ошибок даёт беззнаковый тип: вычитание из нуля в uint даёт огромное число, и цикл с условием «больше либо равно нулю» не заканчивается.