Предисловие

Эта статья из серии с разбором задач отборочного этапа Yandex Cup 2023 по направлению iOS-разработка с призовым фондом почти в 9 000 000 рублей. Повторюсь, правильных ответов у меня не было, и решал я уже после окончания отборочного этапа. Если заметите какие-либо неточности в формулировках, в размышлениях, в ответах, буду рад обсудить это в комментариях.

Начнем!)

Условие

Пример кода
enum ColorComponent {
  case red
  case green
  case blue
}

Известно, что код работает правильно, если enum ColorComponent сможет содержаться в Set. Ваша задача определить, сработает ли код, или понять, что нужно сделать, чтобы его исправить

Варианты ответов

  1. Добавить соответствие протоколу Hashable

  2. Добавить соответствие протоколу Equatable

  3. Добавить соответствие протоколу Comparable

  4. Ничего дополнительно делать не надо

  5. Enum не может содержаться в Set

Мой итоговый ответ

Спойлер
  1. Ничего дополнительно делать не надо

Решение

Для решения данной задачи необходимо понять какие условия должны выполняться элементами, которые мы хотим поместить в контейнер Set. Для этого обратимся к документации:

You can create a set with any element type that conforms to the Hashable protocol. By default, most types in the standard library are hashable, including strings, numeric and Boolean types, enumeration cases without associated values, and even sets themselves.

Во-первых, мы узнали, что условие, которое должно выполняться элементами, помещаемыми в Set — это соответствие протоколу Hashable. В то же время, нужно помнить, что протокол Hashable соответствует протоколу Equatable:

Но в идеале, конечно, не зубрить, а потратить немного времени и понять зачем так было сделано. Ничего сложного тут нет, одна из причин по которой, протокол Hashable соответствует протоколу Equatable, заключается в том, что при проверке на принадлежность объекта к множеству, мы должны по каким-то признакам определять равенство элементов. К примеру, мы хотим добавить новый элемент в контейнер, но по его хэшу уже содержится какое-то значение. Собственно, нам нужно проверить — равен ли добавляемый элемент тому, что уже находится по данному хэшу. Если да, то мы ничего не делаем, в противном случае произошла коллизия (разные объекты имеют одинаковое хэш-значение), в конец односвязного списка по данному хэшу добавится новый объект. А сама логика связанная с хэшированием объектов реализована в структуре Hasher:

Во-вторых, так как наше перечисление не имеет ассоциативных значений, это означает, что оно по умолчанию подписано и реализует протокол Hashable (и в то же время протокол Equatable, как мы разобрались выше). Вы можете подумать, что значениям enum-а по умолчанию задаются целочисленные значения, как в языках С, C++ и Objective-C, а в свою очередь целочисленный тип Int соответствует протоколу Hashable, и по этой причине нам не нужно явно указывать соответствие данному протоколу, но на самом деле тут не все так просто. В языке Swift case-ы перечисления самостоятельны и в текущем примере их типом является ColorComponent.

Особо пытливым предлагаю ознакомиться с документацией языка Swift, там вы сможете более детально разобраться, как все устроено "под капотом" (напишите, пожалуйста, в комментариях или в личные сообщения, если бы вам хотелось видеть еще более глубокий разбор различных инструментов языка, в этом случае я учту это при написании следующих статей):

Разбор ответа №1 (Добавить соответствие протоколу Hashable)

Добавлять соответствия протоколу Hashable не нужно, так как по умолчанию наше перечисление уже соответствует данному протоколу.

Разбор ответа №2 (Добавить соответствие протоколу Equatable)

Добавлять соответствия протоколу Equatable не нужно, так как по умолчанию наше перечисление уже соответствует протоколу Hashable, который соответствует протоколу Equatable.

Разбор ответа №3 (Добавить соответствие протоколу Comparable)

Так как Set в языке Swift представляет из себя неупорядоченную коллекцию уникальных элементов, нам необязательно указывать соответствие протоколу Comparable, но в то же время мы будем обязаны это сделать, если захотим реализовать упорядоченную коллекцию уникальных элементов (Ordered Set).

Разбор ответа №4 (Ничего дополнительно делать не надо)

Данный ответ является верным, в пункте "Решение" приведено объяснение.

Разбор ответа №5 (Enum не может содержаться в Set)

Данный ответ является неверным, в пункте "Решение" приведено объяснение.

Итог

Важно помнить о том, какие условия должны выполняться определенными объектами, чтобы они могли быть помещены в различные коллекции. В самом языке имеется довольно-таки большое количество контейнеров, которые можно использовать для решения различных задач. Наиболее популярными, конечно же, являются String, Set, Dictionary, Array, но хотелось бы упомянуть и чуть менее известные, такие как: Bit Set (для реализации необходимо указать соответствие протоколу OptionSet), Range.

Комментарии (6)


  1. storoj
    13.12.2023 21:18

    Совершенно дебильный вопрос, причём основную дебильность привносят скорее ответы. Считать неправильным ответ "надо законформить Hashable" это почти то же самое, что вопрос про "i+++++i".


    1. storoj
      13.12.2023 21:18

      Статья тоже мусорная: можно сократить до трёх предложений без потери полезного сигнала.


      1. SergeyAbA Автор
        13.12.2023 21:18

        Сам разбор я мог уместить хоть в одном приложение, но решил уделить внимание деталям и разобрать их поподробнее. Все же спасибо за комментарий к моей работе, при написании новых статей, возможно, учту Ваше пожелание.


    1. SergeyAbA Автор
      13.12.2023 21:18

      У каждого свое мнение, лично мне задача понравилась, она с подковыркой, поэтому и ответы такие, иначе тут не сформулируешь.


      1. storoj
        13.12.2023 21:18

        Совершенно бесполезное знание на практике. Если добавишь Hashable в явном виде – хуже не станет. Не добавишь там, где его не хватает – не скомпилируется.


        1. NineNineOne
          13.12.2023 21:18

          Поддерживаю такой ход мыслей. Вот только на собеседованиях такой подход не встречал ни разу, и поэтому специально на своих собесах не задаю такие бесполезные вопросы, а спрашиваю только практику и базу.