> Как реализовать проверку на переполнение при конвертации строки в число (iOS, Swift)

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

Компании: Meta

Стек: iOS, Swift

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

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

Проверка переполнения при конвертации строки в число в Swift сводится к использованию инициализаторов с проверкой границ: Int(string), Double(string) и аналогичные возвращают Optional, а Int(string, radix:) позволяет контролировать основание. Для явной проверки переполнения при арифметических операциях используются addingReportingOverflow, multipliedReportingOverflow и т.д. При парсинге строки важно учитывать locale, формат числа и допустимый диапазон типа - иначе возможны тихие ошибки или краши.

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

В Swift конвертация строки в число безопасна по умолчанию: стандартные инициализаторы возвращают nil при некорректном вводе или выходе за пределы диапазона типа. Например, Int("999999999999999999999") вернёт nil, а не переполненное значение.

Однако есть нюансы:

  • Тип результата: Int - платформозависимый (32/64 бита). Для явного контроля используйте Int64, UInt64 и т.д.
  • Основание системы счисления: Int(string, radix: 16) позволяет парсить hex, но нужно проверять валидность символов.
  • Формат строки: пробелы, знак, десятичный разделитель (точка vs запятая) - Double парсит только точку, иначе вернёт nil.
  • Переполнение при арифметике: если после парсинга вы выполняете операции, используйте addingReportingOverflow и проверяйте .overflow в результате.
  • Locale: NumberFormatter учитывает locale, но его настройка сложнее и требует проверки formatter.number(from:).

Для надёжной проверки переполнения при конвертации строки в число нужно:

  1. Выбрать конкретный тип с фиксированным размером (Int64, UInt32 и т.д.).
  2. Использовать Int64(string) - он вернёт nil при переполнении.
  3. Для чисел с плавающей точкой проверять isFinite после конвертации, так как Double("1e999") вернёт infinity, а не nil.

На практике

На практике для iOS-разработки чаще всего используется Int(string) или Double(string) с обработкой nil. Если нужна строгая проверка переполнения при парсинге больших чисел, применяйте Int64 или UInt64 и проверяйте результат на nil.

Для арифметических операций после парсинга используйте методы с ReportingOverflow:

SWIFT
let (result, overflow) = a.addingReportingOverflow(b)
if overflow { /* обработка */ }

Также полезно помнить про Int(truncatingIfNeeded:) - он не проверяет переполнение, а просто обрезает биты, что может быть нежелательно.

Пример кода

SWIFT
// Безопасный парсинг с проверкой переполнения
func parseToInt64(_ string: String) -> Int64? {
guard let value = Int64(string) else {
print("Ошибка: строка не является числом или выходит за пределы Int64")
return nil
}
return value
}
// Проверка переполнения при арифметике
func addWithOverflowCheck(_ a: Int64, _ b: Int64) -> Int64? {
let (result, overflow) = a.addingReportingOverflow(b)
return overflow ? nil : result
}
// Парсинг Double с проверкой на бесконечность
func parseToFiniteDouble(_ string: String) -> Double? {
guard let value = Double(string), value.isFinite else {
print("Ошибка: не число или infinity")
return nil
}
return value
}
// Пример использования
if let number = parseToInt64("9223372036854775807") {
print("OK: \(number)")
} else {
print("Переполнение или неверный формат")
}
if let sum = addWithOverflowCheck(Int64.max, 1) {
print("Сумма: \(sum)")
} else {
print("Переполнение при сложении")
}

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

Начните с того, что стандартные инициализаторы Swift уже безопасны и возвращают Optional. Затем упомяните, что для явного контроля переполнения при арифметике есть методы с ReportingOverflow. Покажите понимание нюансов: Double может вернуть infinity, Int зависит от платформы, locale влияет на парсинг. Приведите пример с Int64 и проверкой isFinite. Подчеркните, что в production-коде важно не полагаться на молчаливое переполнение, а всегда обрабатывать nil или флаг overflow.

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

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

  • знание стандартных API Swift для безопасной конвертации;
  • понимание разницы между Int и фиксированными типами;
  • умение обрабатывать edge cases: infinity, NaN, пробелы, знак;
  • знание методов ReportingOverflow для арифметики;
  • способность объяснить, почему Int(string) не крашится при переполнении.

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

  • Использование Int(string)! без проверки - краш при некорректном вводе.
  • Игнорирование infinity при парсинге Double.
  • Предположение, что Int всегда 64-битный.
  • Забывают про radix при парсинге hex.
  • Использование NumberFormatter без настройки locale, что приводит к неожиданным результатам.
  • Проверка переполнения только при парсинге, но не при последующих операциях.

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

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