> Как реализовать проверку на переполнение при конвертации строки в число (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:).
Для надёжной проверки переполнения при конвертации строки в число нужно:
- Выбрать конкретный тип с фиксированным размером (
Int64,UInt32и т.д.). - Использовать
Int64(string)- он вернётnilпри переполнении. - Для чисел с плавающей точкой проверять
isFiniteпосле конвертации, так какDouble("1e999")вернётinfinity, а неnil.
На практике
На практике для iOS-разработки чаще всего используется Int(string) или Double(string) с обработкой nil. Если нужна строгая проверка переполнения при парсинге больших чисел, применяйте Int64 или UInt64 и проверяйте результат на nil.
Для арифметических операций после парсинга используйте методы с ReportingOverflow:
SWIFTlet (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, что приводит к неожиданным результатам. - Проверка переполнения только при парсинге, но не при последующих операциях.
> Похожие задачи по mobile
Примеры случаев хранения значений на куче и как устроено выделение памяти для массивов
Как проверить, что число положительное или отрицательное
Как разделить функции для чтения и записи значений
Как реализовать фильтрацию массива с сохранением уникальных элементов и порядка
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью