Нужно ли проверять и обрабатывать крайние случаи, такие как ноль и отрицательные значения при преобразовании числа в строку
Что проверяют
Отличаете ли вы настоящие крайние случаи от выдуманных и знаете ли стандартную библиотеку. Ноль и минус для перевода числа в строку не являются проблемой, а вот переполнение и обратное преобразование являются, и интервьюер ждёт именно этого разделения.
Как отвечать
Сначала уточните, можно ли пользоваться strconv. Если да, то ответ короткий: strconv.Itoa и strconv.FormatInt(n, 10) корректно печатают ноль и отрицательные значения, отдельные ветки под них не нужны. fmt.Sprintf("%d", n) тоже работает, но медленнее из-за рефлексии, для дробных нужен strconv.FormatFloat с явной точностью.
Если просят написать руками, крайние случаи такие:
- ноль: цикл вида
for n > 0не сделает ни одной итерации и вернёт пустую строку, значение обрабатывается отдельной веткой; - отрицательное: знак запоминается, дальше работа идёт с модулем;
- минимальное значение
int64: у него нет положительного двойника, и-nпереполняется молча, без паники. Приём из самой стандартной библиотеки: перевести вuint64и взять-uв беззнаковой арифметике, там переполнения нет; - размер буфера: 20 байт хватает на любое
int64со знаком, поэтому строка собирается с конца в массив, а не конкатенацией.
Отдельно скажите про обратную сторону: strconv.Atoi возвращает ошибку, и её надо проверять, а не игнорировать, там же ловится выход за диапазон.
Где спотыкаются
Придумывают ошибку на отрицательном числе и возвращают error при n < 0. Преобразование определено для всех значений, минус это нормальные данные. Ошибка уместна там, где значение непредставимо, а не там, где оно меньше нуля.
Пишут string(n). В Go это не перевод числа в текст, а трактовка как кодовой точки, string(65) даст букву. Компилятор пропускает такой код для переменной, ругается go vet.
Забывают про переполнение и про производительность. -n на минимальном int64 даёт то же самое число, а fmt.Sprintf в горячем цикле заметно дороже strconv, и на нагруженном участке это всплывает в профиле.