> Как реализовать функцию, которая возвращает 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:
SWIFTfunc 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] напрямую, без обёрток. Функция-обёртка оправдана, если:
- нужно добавить логику (например, логирование, трансформацию значения);
- требуется унифицированный интерфейс для разных источников данных;
- нужно скрыть детали реализации (например, словарь - внутреннее хранилище).
Пример с трансформацией:
SWIFTfunc stringValue(for key: Key) -> String? {return dict[key].map { String(describing: $0) }}
Если словарь хранит [Key: Any], то часто используют as? для приведения типа:
SWIFTfunc 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) - компилятор не позволит, но иногда пытаются через!, что опасно.
> Похожие задачи по mobile
Что выведется в консоли при вызове двух одинаковых функций в протоколе с табличной диспетчеризацией
Какие подходы по обеспечению безопасности мобильного приложения и инфраструктуры применить
Какова временная сложность решения в нотации O
Как оцениваете свой уровень разработчика
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью