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

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

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

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

Написание общих классов и структур данных

Хотя массивы, словари и дополнительные функции являются примерами универсальных шаблонов, мы также можем использовать универсальные шаблоны для создания наших собственных типов данных. Например, я могу создать тип данных стек с обобщенными типами, не относящимися к какому-либо типу данных (числа с плавающей запятой, двойные, целые числа). Стек использует процесс LIFO (последний пришел, первый вышел), в котором новый элемент помещается в верхнюю часть стека, а затем новый элемент выгружается из стека. Мне нравится думать об этом как о стопке карточек, когда они кладутся одна на другую и могут снимать только сверху.

Допустим, я хочу собрать свой собственный стек. Я могу использовать угловые скобки, чтобы указать, что он будет общим, что означает, что я могу решить, ЧТО я хочу складывать при создании стека. В этом случае я хочу создать стек строк, представляющий все книги по кодированию, которые я сейчас читаю.

1: я создаю структуру для представления моего типа данных EricasStack. Обратите внимание, что я использую слово «Generic» в угловых скобках. Я мог бы написать там любое слово (может быть, «тако»?), Которое могло бы заменить значение, которое я использую для этого EricasStack.

2. Я создаю массив Generics, который будет содержать мою стопку книг по кодированию.

3: Я хочу добавлять по две книги в свою стопку, поэтому я пишу функцию, которая ВЫДВИГАЕТ два элемента.

4. Я хочу удалять из своей стопки по две книги за раз, поэтому я пишу функцию, которая возвращает два элемента для POPPED.

5: я создаю экземпляр своего EricasStack с типом ‹String›. Обратите внимание, что сейчас я могу добавлять только строки. Я помещаю две книги в CodingBooksStack, затем помещаю еще две книги (всего четыре книги).

Затем я распечатал то, что содержит мой последний CodingBooksStack.

Вы также можете увидеть распечатку того, что ВЫКЛЮЧАЕТСЯ, когда я вызываю .popTwoItems ().

Еще я мог бы заработать Эрику стопку денег:

Как вы можете видеть выше, ‹› может быть заполнен любым типом, когда я создаю экземпляр своего класса EricasStack.

Написание общих функций

Допустим, я хотел взять Int, а затем скопировать его в массив.

Допустим, я хотел взять строку, а затем продублировать ее в массиве.

Допустим, я хотел взять Float, а затем продублировать его в массиве.

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

Функции и методы могут быть универсальными в контексте универсального типа.

1: я пишу функцию с универсальным типом с именем ‹ItemToDuplicate›, которая принимает элемент и целое число, указывающее, сколько раз копировать ItemToDuplicate.

2: я создаю пустой массив для хранения моего arrayOfDuplicates.

3: я зацикливаю numberOfTimes и каждую команду добавляю ItemToDuplicate в свой массив arrayOfDuplicates.

4: я возвращаю заполненный arrayOfDuplicates.

5: Я распечатываю несколько примеров того, как это работает с разными типами строк, такими как ItemToDuplicate.

Обратите внимание, что я мог также использовать Ints, Doubles, Floats вместо строк.

Ограничение универсальных типов

В приведенном выше примере любой тип данных (Int, Float, String) может использоваться в общей функции duplicateAndMakeArray. Я мог бы уточнить и указать, какой ТИП типа данных я мог бы использовать в этом общем контексте.

Этот процесс можно выполнить с помощью некоторых протоколов, которые являются частью стандартной библиотеки Swift. Некоторые примеры общих ограничивающих протоколов включают hashable (т. Е. Должны иметь возможность уникального представления (кхм, словари - это универсальные шаблоны, ограниченные хешируемым протоколом)), сопоставимые (т. е. должны иметь порядок, подобный числам) и equatable (т. е. должны иметь возможность сравниваться, чтобы быть равными).

Допустим, я хочу написать универсальную функцию, которая находит наименьшее значение в массиве. Если я пытаюсь найти НАИБОЛЬШЕЕ значение, это означает, что мне нужно соответствовать протоколу Comparable, о котором я упоминал ранее.

1: я объявляю функцию с общим ‹Type›, которая соответствует протоколу Comparable. Обратите внимание, что протокол, как обычно, указывается после «:». Я беру массив универсального типа и возвращаю ровно одно необязательное значение типа (которое будет наименьшим значением в массиве).

2. Я проверяю, не пуст ли массив. Если это так, я возвращаю ноль.

3: я беру первый элемент во введенном массиве и идентифицирую его как «itemToCompare».

4: Я просматриваю весь массив и, зацикливаясь, сравниваю первый элемент с каждым последующим элементом.

5 и 6:. Если мой itemToCompare больше, чем каждый последующий элемент, я переназначаю itemToCompare на этот более крупный элемент.

7: Если нет, я возвращаю itemToCompare.

8: я вызываю функцию findSmallestInArray с помощью Ints.

9: я вызываю функцию findSmallestInArray с двойными значениями.

Этот пример - всего лишь один из способов использования протоколов для ограничения универсальных типов для написанных универсальных функций.

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

В третьей части моих публикаций по обобщениям я буду обсуждать связанные типы и предложения Where.

Ресурсы:

Документация Apple - Обобщения