> Как реализовать добавление цифр к результату с помощью append и слайса байт в Go (Go)

Уровень: middle · Роль: backend · Категория: Технические вопросы

Компании: МайлРу

Стек: Go

> Пример ответа

Короткий ответ

Чтобы добавить цифры к результату в Go, используют strconv.AppendInt, strconv.AppendUint или strconv.AppendFloat - они принимают слайс байт как первый аргумент и возвращают расширенный слайс. Альтернативно можно вручную конвертировать цифру в байт через byte('0' + digit) и делать append. Основной принцип: append мутирует слайс при достаточной ёмкости или выделяет новый, поэтому результат всегда присваивают обратно.

Подробное объяснение

append в Go работает с любым типом элемента, включая byte. Для цифр есть два подхода:

  1. Через strconv - стандартный способ для чисел любой разрядности. Функции вида AppendInt(dst []byte, i int64, base int) []byte добавляют строковое представление числа к существующему слайсу. Это эффективно, так как не создаёт промежуточную строку.

  2. Вручную - если нужно добавить одну цифру от 0 до 9, можно использовать арифметику: digit := n % 10, затем result = append(result, byte('0'+digit)). Это работает, потому что коды символов цифр идут подряд.

Важно понимать поведение append: если ёмкость слайса достаточна, он перезапишет элементы за текущей длиной и вернёт тот же слайс с увеличенной длиной. Если нет - выделит новый массив. Поэтому всегда нужно использовать возвращаемое значение: result = append(result, b).

При добавлении нескольких цифр числа (например, при ручной конвертации int в строку) порядок будет обратным - сначала получаем младший разряд, поэтому либо идём с конца числа, либо разворачиваем результат в конце.

На практике

Типичный сценарий - сборка строки или буфера из чисел без лишних аллокаций. Например, при формировании HTTP-ответа или сериализации. Вместо fmt.Sprintf и последующей конкатенации используют append с strconv, чтобы избежать создания промежуточных строк.

Для однозначных чисел ручной способ через byte('0'+digit) быстрее, чем вызов strconv, но для многозначных лучше использовать strconv.AppendInt - он уже оптимизирован.

Если нужно добавить цифру в начало результата, удобнее сначала собрать в обратном порядке, а затем развернуть слайс через slices.Reverse (Go 1.21+) или вручную.

Пример кода

GO
package main
import (
"fmt"
"strconv"
)
func main() {
// Способ 1: через strconv
result := make([]byte, 0, 16)
result = strconv.AppendInt(result, 12345, 10)
result = append(result, ' ') // добавляем пробел
result = strconv.AppendInt(result, -678, 10)
fmt.Println(string(result)) // "12345 -678"
// Способ 2: ручное добавление одной цифры
var digits []byte
n := 7
digits = append(digits, byte('0'+n))
fmt.Println(string(digits)) // "7"
// Способ 3: ручная конвертация многозначного числа
num := 9876
var buf []byte
for num > 0 {
digit := num % 10
buf = append(buf, byte('0'+digit))
num /= 10
}
// разворачиваем, так как цифры собраны в обратном порядке
for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
buf[i], buf[j] = buf[j], buf[i]
}
fmt.Println(string(buf)) // "9876"
}

Как отвечать на собеседовании

Начни с упоминания strconv.AppendInt как основного инструмента, затем покажи ручной способ для одиночных цифр. Обязательно подчеркни, почему результат append нужно присваивать обратно - это частый вопрос на понимание устройства слайсов. Приведи пример с буфером и объясни, почему это эффективнее конкатенации строк. Если спросят про производительность, скажи, что append с предварительным выделением ёмкости (make([]byte, 0, n)) избегает лишних аллокаций.

Что проверяет интервьюер

Интервьюер оценивает:

  • понимание работы append и слайсов (ёмкость, длина, возможное перераспределение);
  • знание стандартной библиотеки (strconv);
  • умение работать с байтами и кодами символов;
  • способность написать код без лишних аллокаций и промежуточных строк.

Типичные ошибки

  • Игнорирование возвращаемого значения append - если ёмкость превышена, исходный слайс не изменится, и данные потеряются.
  • Попытка добавить цифру как append(result, digit) без преобразования в byte - получится не символ, а управляющий код.
  • Забывают про обратный порядок при ручной конвертации числа в строку.
  • Использование fmt.Sprintf внутри цикла для каждой цифры - это создаёт лишние аллокации и замедляет код.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью