> Как правильно обрабатывать нулевое значение при преобразовании числа в строку (Go)

Уровень: senior · Роль: backend · Язык: Go · Категория: Кодинг

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

Стек: Go

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

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

В Go нет универсального null для чисел, поэтому важно различать zero value и отсутствие значения. Для int ноль - валидное значение, и его нельзя путать с отсутствием. Если отсутствие возможно, используйте *int, sql.NullInt64 или optional-тип и явно решайте, что выводить: "0", "" или "null". Решение должно быть согласовано на уровне API-контракта, а не спрятано в форматировании.

Подход к решению

Сначала определите семантику: ноль - это реальное число или отсутствие данных. Для реального нуля используйте strconv.Itoa или strconv.FormatInt и получите "0". Для отсутствия значения применяйте указатель или специализированный тип и проверяйте его перед преобразованием. Если API ожидает JSON, не смешивайте omitempty с бизнес-логикой: omitempty уберёт и 0, и nil. Лучше явно управлять сериализацией через кастомный MarshalJSON или DTO. На senior-уровне важно проговорить trade-off между простотой zero value и точностью nullable-модели.

Пример кода

GO
package main
import (
"encoding/json"
"fmt"
"strconv"
)
type User struct {
Age *int `json:"age"`
}
func formatAge(age *int) string {
if age == nil {
return "null"
}
return strconv.Itoa(*age)
}
func main() {
zero := 0
user := User{Age: &zero}
fmt.Println(formatAge(user.Age)) // "0"
fmt.Println(formatAge(nil)) // "null"
b, _ := json.Marshal(user)
fmt.Println(string(b)) // {"age":0}
}

Edge cases

Указатель может быть nil, а значение по указателю - нулевым. sql.NullInt64 требует проверки Valid. omitempty для int скрывает 0, а для *int скрывает nil. При парсинге "0" и "" ведут себя по-разному. В конкурентном коде указатель может измениться между проверкой и разыменованием. Для json.Number ноль сохраняется как "0", но отсутствие поля даёт nil. Также учитывайте локали и формат null в разных API.

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

Начните с уточнения: ноль - это данные или отсутствие. Затем предложите модель: *int, sql.NullInt64 или отдельный optional-тип. Покажите, как избежать случайного omitempty. Приведите пример с strconv и MarshalJSON. Объясните trade-off: простота против точности контракта. Упомяните тесты на nil, 0 и отсутствующее поле. Если речь о БД, добавьте sql.NullInt64 и проверку Valid.

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

Понимание разницы между zero value и null в Go. Умение выбирать представление отсутствующего значения. Знание strconv, encoding/json и omitempty. Навык проектирования API-контракта. Внимание к edge cases и конкурентности. Способность объяснить trade-off на уровне senior.

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

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