Любопытная универсальность связанных типов в Swift

Объединять или не объединять - вот в чем вопрос!

Прежде чем мы углубимся, протоколы!

Swift представил новую парадигму под названием POP или Protocol Oriented Programming. Для людей, плохо знакомых со Swift, особенно тех, кто пришел с тяжелого языка ООП, такого как Java или C #, протоколы могут показаться чем-то вроде интерфейсов. По крайней мере, так кажется на первый взгляд. Когда дело доходит до реализации, протоколы - это совсем другое дело, чем интерфейсы. (Не говоря уже о дополнительных преимуществах, которые приносят протоколы.)

Допустим, вы хотите иметь протокол с методом, который складывает два числа и возвращает сумму. А пока давайте просто представим, что мы будем добавлять только числа типа Int.

Теперь нам нужно добавить реализацию для этого метода, верно? Так как же нам это сделать? Мы создаем class, который conforms для этого протокола.

Посмотрим, сработает это или нет!

А что, если мы хотим не просто добавить Int, а добавить числа типа Float и Double? Подожди секунду, я знаю, ты будешь выкрикивать дженерики. Есть еще один способ с протоколами. Мы можем использовать Associated Types.

В погоне за ваббитом ... Что такое ассоциированный тип?

Мы хотим, чтобы наш метод протокола был универсальным, верно? Это означает, что мы должны указать ему, чтобы он также принял некоторый общий тип. Но возможно ли это? Определенный нами протокол ни в коем случае не является универсальным. Я имею в виду, что нет особой подписи, чтобы он был универсальным! Оказывается, на самом деле все наоборот. Вы можете определить общий тип внутри протокола. А связанные типы просто позволяют вам это делать. Давайте посмотрим на пример.

Обратите внимание на разницу: мы создали тип из ниоткуда, и теперь наша функция может с ним работать!

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

Другими словами, associatedtype дает вашему воображаемому типу имя / идентификатор, чтобы он не терялся в толпе.

Немного формальное определение

Если вы хотите определить и associatedtype формально, как это сделала Apple (я только что поделился этим из приложения Apple Books) -

Связанный тип дает имя-заполнитель для типа, который используется как часть протокола. Фактический тип, используемый для этого связанного типа, не указывается до тех пор, пока протокол не будет принят. Связанные типы указываются с помощью ключевого слова connectedtype.

Отрывок из Язык программирования Swift (Swift 4.2) Apple Inc. https://books.apple.com / us / book / the-swift-programming-language-swift-5-0 / id881256329 Этот материал может быть защищен авторским правом.

Вернемся к делу

Давайте добавим реализацию для протокола. На этот раз давайте добавим Double типов чисел. Прежде чем мы это сделаем, мы должны задать очень важный вопрос - как сообщить нашему общему методу протокола, какой тип мы собираемся передать?

Типалиас спешат на помощь!

Нам просто нужно добавить typealias для associatedtype в классе, соответствующем протоколу. Как нам это сделать? Просто назначьте тип, который должна принимать функция, как typealias. Хорошо, давайте еще раз посмотрим код.

Теперь, когда с этим разобрались, перейдем к самой функции.

Полный DoubleAdder теперь выглядит так.

Снова тестирование, реализация отключается.

Так интерфейсы тьфу, протоколы могут быть общими, а?

Оказывается, так оно и есть! Протоколы со связанными типами могут использоваться как универсальные типы. Но стоит ли использовать их вместо проверенных и проверенных существующих универсальных типов? Я считаю, что это потребует серьезного обсуждения, и мне не следует больше публиковать этот пост. Давай оставим это для отдельного поста, ладно? Большой! Увидимся до тех пор и держи себя в руках!

Эхм, просто хочу сказать, что вы также можете прочитать материалы, связанные с этим в моем блоге.