> Как реализовать функцию, которая возвращает nil или значение из словаря (iOS, Swift)

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

Компании: Revolut

Стек: iOS, Swift

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

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

В Swift словарь возвращает Optional при обращении по ключу: dict[key] уже возвращает Value?. Если нужно вернуть nil при отсутствии ключа или явно преобразовать значение, используйте dict[key] напрямую или метод first(where:) для кастомной логики. Для безопасного извлечения с дефолтным значением - dict[key, default: value]. Функция-обёртка может выглядеть так: func value(for key: Key) -> Value? { dict[key] }.

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

Словарь в Swift - это коллекция пар "ключ-значение", где ключи уникальны и хешируемы. Обращение по ключу через subscript всегда возвращает Optional<Value>, потому что ключ может отсутствовать. Это фундаментальное поведение, заложенное в тип Dictionary.

Если требуется функция, которая возвращает nil или значение, достаточно обернуть subscript:

SWIFT
func lookup(_ key: Key) -> Value? {
return dict[key]
}

Но есть нюансы. Если ключ присутствует, но значение - nil (что невозможно для Dictionary, но возможно для [Key: Value?]), то subscript вернёт Optional<Optional<Value>> - двойную опциональность. Для таких случаев используйте flatMap или compactMap.

Также можно использовать first(where:) для поиска по условию, а не по точному ключу. Это полезно, когда нужно найти значение по частичному совпадению или по вычисляемому свойству ключа.

Для производительности: subscript по ключу - O(1), first(where:) - O(n). Выбор зависит от задачи.

На практике

В реальном коде чаще всего используют dict[key] напрямую, без обёрток. Функция-обёртка оправдана, если:

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

Пример с трансформацией:

SWIFT
func stringValue(for key: Key) -> String? {
return dict[key].map { String(describing: $0) }
}

Если словарь хранит [Key: Any], то часто используют as? для приведения типа:

SWIFT
func intValue(for key: Key) -> Int? {
return dict[key] as? Int
}

Пример кода

SWIFT
// Базовый случай
func value(for key: String, in dict: [String: Int]) -> Int? {
return dict[key]
}
// С двойной опциональностью
func value(for key: String, in dict: [String: Int?]) -> Int? {
return dict[key] ?? nil
}
// Поиск по условию
func findValue(where predicate: (String) -> Bool, in dict: [String: Int]) -> Int? {
return dict.first(where: { predicate($0.key) })?.value
}
// С дефолтным значением
func valueOrZero(for key: String, in dict: [String: Int]) -> Int {
return dict[key, default: 0]
}

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

Начните с того, что subscript словаря уже возвращает Optional - это ключевой момент. Затем уточните, зачем нужна отдельная функция: если просто вернуть значение, обёртка избыточна. Если нужна дополнительная логика - покажите пример с map, flatMap или first(where:). Упомяните сложность операций и разницу между dict[key] и first(where:). Если спросят про [Key: Value?] - объясните двойную опциональность и способы её схлопывания.

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

  • Понимание опциональности в Swift и её связи с Dictionary.
  • Умение работать с Optional-цепочками и преобразованиями.
  • Знание стандартных методов коллекций (map, first, compactMap).
  • Понимание trade-off между простотой и производительностью.
  • Способность объяснить, когда обёртка оправдана, а когда - нет.

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

  • Забывают, что subscript уже возвращает Optional, и пишут лишние if let внутри обёртки.
  • Путают dict[key] и dict.first(where:) - первое O(1), второе O(n).
  • Не учитывают двойную опциональность для [Key: Value?].
  • Используют as! вместо as? при работе с [String: Any] - это приводит к crash.
  • Возвращают dict[key] из функции, объявленной как Value (не Optional) - компилятор не позволит, но иногда пытаются через !, что опасно.

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

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