Как правильно обрабатывать нулевое значение при преобразовании числа в строку
Что проверяют
Чаще всего это задача написать перевод числа в строку без strconv и проверка, не забудете ли вы граничные случаи. Ноль тут первый: наивный цикл на нём возвращает пустую строку. Следом просят обработать отрицательные числа и math.MinInt64.
Как отвечать
Сначала назовите стандартный путь: strconv.Itoa(n) для int, strconv.FormatInt(n, 10) для int64, strconv.AppendInt для записи в готовый буфер без лишних аллокаций. fmt.Sprint тоже работает, но медленнее.
Если нужно написать руками, проговорите граничные случаи до кода:
- ноль: цикл
for n > 0не выполнится ни разу. Либо обработайте0отдельно, либо проверяйте условие в конце итерации, чтобы хотя бы одна цифра записалась; - отрицательные числа: запомните знак и работайте с модулем;
math.MinInt64: у него нет положительной пары вint64, и-nснова даёт отрицательное число. Надёжный приём:u := uint64(n), а для отрицательногоu = -u, беззнаковое отрицание корректно даёт модуль;- порядок цифр: остатки от деления на 10 идут с конца, поэтому заполняйте массив
[20]byteсправа налево и возвращайтеstring(buf[i:]). Двадцати байт хватает на 19 цифр и знак.
Если же вопрос про «нулевое значение» в смысле zero value, разведите два случая. Ноль как значение и отсутствие значения в Go выглядят одинаково, поэтому для «не задано» берут *int, sql.NullInt64 или отдельный флаг. Функция с указателем обязана проверить nil, прежде чем разыменовывать.
Где спотыкаются
Пишут string(n) и получают символ с кодом n, а не цифры: при n := 65 результат "A". go vet на такое преобразование предупреждает.
Проверяют решение на 123 и -45, но не на 0 и не на math.MinInt64. Интервьюер почти всегда подаёт именно эти два значения.
Не замечают, как zero value теряется при сериализации: поле с тегом json:",omitempty" и значением 0 пропадает из JSON, и клиент не отличает ноль от отсутствия.