Connect with us

Программирование

Как использовать дженерики в Swift

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

Опубликовано

/

     
     

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

Зачем нам нужны дженерики в Swift?

class SearchUtil{
var list: [Int] = []
init(list: [Int]) {
self.list = list
}
func searchItem(element: Int, foundItem: (Int?)->()) {
let itemFoundList = self.list.filter { item in
item == element
}
if (itemFoundList.isEmpty){
foundItem(nil)
}
else{
foundItem(itemFoundList.first)
}
}
}
let searchUtil = SearchUtil(list: [Int](arrayLiteral: 24,25,26))
searchUtil.searchItem(element: 23) {(result) -> () in
print(result ?? "Not found")
}

Как видите, класс SearchUtil принимает в качестве параметра список целых чисел. Функция searchItem возьмет целое число (которое необходимо найти) в качестве входных данных и вернет результат. Это кажется прекрасным, не так ли? Тогда в чем проблема?

Предположим, теперь вам нужно найти элемент в массиве строк или объектов. Что вы будете делать? Есть два возможных решения этой проблемы.

  • Создать еще один класс SearchUtil и функцию searchItem, которая будет принимать строки или объекты и возвращать результат.
  • Использовать дженерики.

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

Что такое дженерики?

Согласно официальной документации,

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

Дженерики (Универсальные шаблоны, Generics) — это классы, структуры, интерфейсы и методы, которые имеют заполнители (параметры типа) для одного или нескольких типов, которые они хранят или используют. Универсальный класс коллекции может использовать параметр типа в качестве заполнителя для типа хранимых в нем объектов; параметры типа отображаются как типы его полей и типы параметров его методов. Универсальный метод может использовать свой параметр типа как тип возвращаемого значения или как тип одного из своих формальных параметров.

В двух словах:

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

Думаю, это самое простое объяснение.

Дженерики в действии

Теперь мы преобразуем приведенный выше пример в дженерики. Чтобы преобразовать класс SearchUtil в Generics, нам нужно изменить его, как показано ниже.

class SearchUtil<T: Equatable>

Здесь T указывает, что в качестве аргумента может быть использован любой тип. Я использовал протокол Equatable, потому что объект будет проверяться на равенство.

Также нам нужно изменить функцию searchItem.

func searchItem(element: T, foundItem: (T?)->())

Теперь мы можем использовать любой тип, который мы хотим.

let searchUtil = SearchUtil(list : listOfObjects)
let searchUtil = SearchUtil(list : listOfNumber)

Приведенный выше код будет работать без каких-либо проблем. Давайте посмотрим на реальный пример.

struct Person: Equatable{
let name: String
let email: String
let age: Int
}
func search() {
let henry = Person(name : "Henry", email : "henry@email.com", age : 24)
let robert = Person(name : "Robert", email : "robert@email.com", age : 22)
let tom = Person(name : "Tom", email : "tom@email.com", age : 25)
let listOfPerson = Array(arrayLiteral: henry, robert, tom)
let searchUtil = SearchUtil(list : listOfPerson)
searchUtil.searchItem(element: henry) {(result) -> () in
print(result ?? "Not found")
}
}
class SearchUtil<T: Equatable>{
var list: [T] = []
init(list: [T]) {
self.list = list
}
func searchItem(element: T, foundItem: (T?)->()) {
let itemFoundList = self.list.filter { item in
item == element
}
if (itemFoundList.isEmpty){
foundItem(nil)
}
else{
foundItem(itemFoundList.first)
}
}
}
search()

Здесь мы создали структуру Person. Мы выполняем операцию поиска в listOfPerson. Теперь, если вы хотите выполнить операцию поиска в списке целых чисел, вы можете сделать это без каких-либо изменений в SearchUtil или searchItem.

let searchUtil = SearchUtil(list: [Int](arrayLiteral: 24,25,26))
    searchUtil.searchItem(element: 26) {(result) -> () in
        print(result ?? "Not found")
}

Это потрясающе, не правда ли?

Источник

Дополнительное видео

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.
Telegram

Популярное

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: