Как реализовать добавление цифр к результату с помощью append и слайса байт в Go
Что проверяют
Понимаете ли вы, как устроен слайс и что делает append, и умеете ли превратить число в текст без лишних аллокаций. Следом обычно спрашивают, почему функция, которая добавляет в переданный слайс, иногда «теряет» результат у вызывающего.
Как отвечать
Начните с устройства: слайс это указатель на массив, длина и ёмкость. append пишет в свободную ёмкость, а если её не хватает, выделяет массив побольше и копирует данные. Поэтому результат всегда присваивают: buf = append(buf, x).
Каркас решения:
- цифра в символ:
byte('0' + d)дляdот 0 до 9, коды цифр в ASCII идут подряд; - число целиком: цифры получаются через
n % 10иn /= 10, то есть с конца. Их либо разворачивают после цикла, либо пишут в локальный[20]byteс конца и добавляют хвост однимappend(buf, tmp[i:]...); - знак: минус обрабатывают отдельно. У
math.MinInt64нет положительной пары вint64, поэтому модуль удобнее считать вuint64; - стандартная библиотека: в реальном коде это
strconv.AppendInt(buf, n, 10), рядомstrconv.AppendFloatиstrconv.AppendQuote. Они пишут прямо в ваш буфер, без промежуточной строки; - предвыделение: если размер известен,
make([]byte, 0, n)избавит от перевыделений.
В конце string(buf) копирует байты в новую строку. Для сборки большого текста покажите strings.Builder или bytes.Buffer, у них есть Grow для той же цели.
Где спотыкаются
Пишут string(d) и ждут «5». Получается символ с кодом 5, а не цифра; go vet такое преобразование помечает. С string(rune(d)) ошибка та же, только уже без предупреждения. Нужны strconv.Itoa или '0' + d.
Передают слайс в функцию, делают там append и ничего не возвращают. Если ёмкости хватило, данные легли в общий массив, но длина у вызывающего прежняя, и он их не видит. Функция должна возвращать новый слайс, как strconv.AppendInt.
Добавляют в подслайс a[:2] и перезаписывают элементы исходного a, потому что массив у них общий. Помогает полное выражение среза a[:2:2], оно ограничивает ёмкость.