Разбор задачи A отборочного этапа Yandex Cup 2023 — iOS
Предисловие
Недавно закончился отборочный этап Yandex Cup для разработчиков по различным направлениям, одним из которых была мобильная разработка под iOS. Как раз про нее и поговорим, а точнее про задания, которые были там представлены. Стоит отметить, что их сложность выше среднего, по этой причине, думаю, каждый подчеркнет для себя что-нибудь новое. Хотелось бы сразу сказать о том, что некоторые используемые конструкции/инструменты языка/фреймворков были для меня не новы, но в жизни встречался с ними редко, поэтому приходилось читать и на практике воспроизводить код из условия, экспериментируя с ним. Правильных ответов у меня не было, и решал я уже после окончания отборочного этапа. Если заметите какие-либо неточности в формулировках, в размышлениях, в ответах, буду рад обсудить это в комментариях.
Приступим!)
Условие
Варианты ответов:
оператор должен быть postfix
@escaping в объявлении избыточен
@autoclosure в объявлении избыточен
throws в объявлении избыточен
тип переменной v в данном случае является типом неопционального(Wrapped) значения
данный код не скомпилируется
Wrapped в данном примере является generic типом
для такого объявления нужно объявить собственный тип ошибки вместо типа Error
без явного задания precedence group оператор будет объявлен с DefaultPrecedence
Мой итоговый ответ:
Спойлер
@escapingв объявлении избыточен
Wrapped в данном примере является generic типом
без явного задания precedence group оператор будет объявлен с DefaultPrecedence
Разбор ответа №1 (оператор должен быть postfix)
В языке Swift имеется возможность создавать "Пользовательские операторы", используя ключевое слово "operator"
Сам оператор может находиться в одной из трех позиций, которые определяются модификаторами: prefix (перед операндом), infix (между операндами), postfix (после операнда)
В данном случае на глобальном уровне определяется пользовательский оператор:
infix operator !!
В расширении Optional-а реализована функция самого перечисления, которая принимает несколько параметров:
v: Self,
e: @escaping @autoclosure () -> Error
Следовательно модификатора postfix здесь быть не может, как и модификатора prefix, так как они работают с одним операндом.
Разбор ответа №2 (@escaping в объявлении избыточен):
@escaping— это атрибут безымянной функции (в простонародье "closure"), который используется для изменения жизненного цикла замыкания, позволяя ему "сбежать" после завершения функции, в которую он был передан
Собственно, в данном примере нам не за чем помечать наш closure атрибутом @escaping , так как он нам не нужен вне данной функции
Разбор ответа №3 (@autoclosure в объявлении избыточен):
@autoclosure— это ещё один из атрибутов замыкания, который позволяет преобразовать передаваемое значение (аргумент функции) в соответствующее возвращаемому типу (в нашем случае типу, реализующему протокол Error) автозамыкание
В данном случае атрибут @autoclosureне избыточен, его можно оставить (но лучше его не использовать, так как он снижает читаемость кода)
Разбор ответа №4 (throws в объявлении избыточен):
В теле метода указано, что мы выбрасываем исключение, используя ключевое слово "throw":
throw e()
Получается и при объявлении функции мы обязаны указать, что она выбрасывает исключения, которые необходимо обработать:
) throws -> Wrapped
Разбор ответа №5 (тип переменной v в данном случае является типом неопционального(Wrapped) значения):
Если бы тип переменной v был неопциональным(Wrapped), то и смысла в этом методе не было бы, так как он как раз таки и "раскрывает" опциональный(Wrapped).
Разбор ответа №6 (данный код не скомпилируется):
Нет причин, по которым он не должен компилироваться.
Разбор ответа №7 (Wrapped в данном примере является generic типом):
Да Wrapped является generic типом, так как мы не можем однозначно сказать какой тип у возвращаемого значения функции.
Разбор ответа №8 (для такого объявления нужно объявить собственный тип ошибки вместо типа Error):
В целом, это можно сделать, но это необязательно. Мы просто должны в качестве возвращаемого значения замыкания передать объект, тип которого реализует протокол Error.
Разбор ответа №9 (без явного задания precedence group оператор будет объявлен с DefaultPrecedence):
По умолчанию, если мы не задаем precedence group, то оператор будет объявлен с DefaultPrecedence:
The infix operators are grouped below by precedence group in decreasing order of precedence. If you declare a new operator without specifying a precedence group, it is a member of the
DefaultPrecedence
precedence group.DefaultPrecedence
has no associativity and a precedence immediately higher thanTernaryPrecedence
.
Авторы
Сергей А.
Middle iOS-developer, стажер-исследователь НУЛ ОиМТ ДПИ ФКН НИУ ВШЭ