> Как реализовать функцию умножения числа на десять с обработкой символов (iOS, Swift)

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

Компании: Meta

Стек: iOS, Swift

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

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

Функция умножения числа на десять с обработкой символов в Swift должна принимать строку, валидировать её содержимое (цифры, знак, десятичный разделитель), преобразовывать в число с учётом локали и возвращать результат. Ключевые моменты - корректная обработка Decimal для точности, учёт Locale для разделителя и явная обработка ошибок вместо force unwrapping. Для iOS важно использовать Decimal вместо Double, чтобы избежать ошибок округления при работе с денежными значениями.

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

Основная задача - не просто умножить число, а корректно обработать строковое представление. В Swift есть несколько подходов:

  1. Decimal + Decimal(string:locale:) - рекомендуемый способ для финансовых расчётов. Инициализатор автоматически учитывает разделитель из локали, но требует явной передачи Locale для предсказуемости.

  2. Double + Double(string) - проще, но теряет точность для чисел с плавающей точкой (например, 0.1 * 10 даст 1.0000000000000002).

  3. Ручной парсинг - нужен только если требуется строгая валидация формата (например, запрет научной нотации или множественных разделителей).

Обработка символов включает:

  • Проверку на nil после инициализации
  • Отсечение пробелов и невидимых символов
  • Учёт знака +/-
  • Обработку пустой строки

На практике

Для production-кода используйте Decimal и явно передавайте Locale.current или конкретную локаль, если формат фиксирован. Функция должна возвращать Result<Decimal, Error> или Decimal? с понятным nil для ошибок. Не используйте try! или force unwrap - это приведёт к крашу приложения.

Пример типичной реализации:

SWIFT
func multiplyByTen(_ input: String) -> Decimal? {
let trimmed = input.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { return nil }
guard let number = Decimal(string: trimmed, locale: Locale.current) else {
return nil
}
return number * 10
}

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

SWIFT
let allowed = CharacterSet(charactersIn: "0123456789.,+-")
guard trimmed.rangeOfCharacter(from: allowed.inverted) == nil else { return nil }

Пример кода

Полная версия с обработкой ошибок:

SWIFT
enum MultiplyError: Error {
case emptyInput
case invalidFormat
}
func multiplyByTen(_ input: String) -> Result<Decimal, MultiplyError> {
let trimmed = input.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else {
return .failure(.emptyInput)
}
guard let number = Decimal(string: trimmed, locale: Locale.current) else {
return .failure(.invalidFormat)
}
return .success(number * 10)
}
// Использование
let result = multiplyByTen("12.5")
switch result {
case .success(let value):
print(value) // 125
case .failure(let error):
print(error)
}

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

Начните с вопроса об уточнении: "Речь идёт о строковом вводе или числовом?" Это покажет внимание к деталям. Затем объясните выбор Decimal над Double - это ключевой момент для senior-позиции. Упомяните локализацию: "В iOS разделитель зависит от региона, поэтому нужно передавать Locale". Покажите понимание обработки ошибок: "Возвращаю Result, чтобы caller мог обработать ошибку без краша". Если спросят про производительность - отметьте, что Decimal медленнее Double, но для UI-операций это некритично.

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

  • Понимание разницы между Decimal и Double для финансовых вычислений
  • Умение работать с Locale и строковыми представлениями чисел
  • Навыки defensive programming (обработка пустых строк, невалидных символов)
  • Способность выбрать правильный API (Decimal(string:locale:) vs ручной парсинг)
  • Понимание Result type и паттернов обработки ошибок в Swift

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

  • Использование Double без учёта точности - приводит к ошибкам округления
  • Игнорирование Locale - функция работает только для одного формата чисел
  • Force unwrap (try! или !) - краш при невалидном вводе
  • Отсутствие проверки на пустую строку - Decimal(string: "") вернёт nil, но это не всегда очевидно
  • Умножение строки через * - невозможно, кандидат должен понимать необходимость преобразования
  • Необработка символов валют или пробелов - нужно явно триммить и валидировать

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

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