Изучая Swift, я заметил, что некоторые функции запрашивают параметр типа Element. Меня немного смутило, почему нас просили указать переменную типа , о которой я никогда не слышал в чем-то настолько знакомом, как массив ...

Например, давайте посмотрим на метод append (), вызываемый для массива String .

Когда мы используем автозаполнение для завершения функции добавления, нам предлагается один аргумент: newElement: Element. Поскольку мы уже знаем, что массив содержит строки, почему параметр введите String?

Метод добавления принимает String и печатает метод с новой строкой, добавленной в конец Array . Итак, что здесь происходит? Почему меня просят предоставить методу элемент, но он принимает String?

Давайте на секунду подумаем о массивах. Каждый созданный нами массив имеет доступный метод append (), но не все массивы однотипны. Вместо того, чтобы использовать append () в массиве строк, давайте попробуем его на Интеллектуальный массив.

Отлично! даже несмотря на то, что тип нашего массива изменился с [String] на [Int], мы можем использовать Элемент, чтобы передать параметр String или Int. Поскольку тип элементов в массиве меняется, использование Element позволяет нам передать правильный тип в соответствии с тем, что находится в нашем массиве .

Но все же .. что такое Элемент? Это класс? Struct? Оказывается, это связано с чем-то, что называется Общий код. Вот это прямо из документации Apple:

«Общий код» позволяет вам писать гибкие многоразовые функции и типы, которые могут работать с любым типом в соответствии с определенными вами требованиями. Вы можете написать код, который избегает дублирования и ясно и абстрактно выражает свои намерения ».

Тип заполнителя

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

Давайте посмотрим на синтаксис нормальной функции и функции, использующей Generics.

Вот функция, которая принимает строку и возвращает ее как отдельный элемент массива. Мы видим, что функция ограничивается только получением строк и возвратом массива строк.

Во втором примере мы видим общий код, позволяющий одному и тому же методу принимать параметр любого типа и возвращать массив любого типа. Это дает функции значительное увеличение функциональности.

Синтаксис

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

Прежде всего, вы должны заметить, что тип заполнителя объявляется сразу после имени функции в угловых скобках. В предыдущих примерах мы использовали слово «Элемент», но давайте изменим его здесь. Вы можете назвать это как угодно, но это должно указывать на то, что вы ищете в качестве аргумента. Давайте использовать ‹T› для типа.

Затем вы можете увидеть, что тип заполнителя используется для объявления типа параметра. Обратите внимание, что если у вас есть несколько параметров в вашей функции, которые относятся к типу заполнителя, все они должны соответствовать одному и тому же типу при вызове функции. Если вы попытаетесь вызвать функцию с разными типами, передаваемыми в параметры заполнителей, вы увидите ошибку.

Наконец, мы видим, что возвращаемая переменная также использует тип заполнителя. Если мы собираемся вернуть массив, нам нужно явно указать тип массива. Поскольку мы еще не знаем, что это за тип, мы можем снова использовать наш тип заполнителя, чтобы работать как… заполнитель.

Теперь, когда мы автоматически завершаем createArray (), мы видим, что он запрашивает у нас два значения типа T. Но теперь мы знаем, откуда взялся T.

И работает с разными типами!

Мы также можем поместить несколько типов заполнителей между угловыми скобками в нашей сигнатуре функций. Они должны быть разделены запятой, чтобы параметры функции могли принимать разные типы.

В качестве заключительного примечания - рекомендуется давать типу параметра имя, чтобы описать связь между параметром и тем, для чего он используется. Если вы видите ‹Element›, вы должны знать, что работаете с массивом. Используя ‹Key› и ‹Value›, вы знаете, что будете работать со словарем.

Если параметр не является конкретным в отношении того, в чем он используется - вы можете назвать его как хотите! Обычно вы используете отдельные буквы, такие как ‹T› или ‹V›.