Site icon AppTractor

Swift 5: полезные протоколы, чтобы писать как профессионал

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

1. CaseIterable

Протокол CaseIterable позволяет получать все значения типа. Давайте посмотрим на примере.

Без CaseIterable:

enum City {
    case new_york
    case bei_jing
    case vancouver
    ....
}

let cities: [City] = [.new_york, .bei_jing, .vancouver, ....]

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

С CaseIterable:

enum City: CaseIterable {
    case new_york
    case bei_jing
    case vancouver
    ....
}

let cities = City.allCases

С помощью свойства allCases, предоставляемого протоколом CaseIterable, мы можем получить массив всех City. Это может значительно сэкономить время.

2. CustomStringConvertible

Не всем нравится описание по умолчанию для каждого объекта. Иногда мы хотим дать объекту более удобное описание только для чтения и распознавания.

Без CustomStringConvertible:

struct Weather {
   let city: String
   let temperature: Double
}

let weather = Weather(city: "New York", temperature: 97.5)

print("The temperature in \(weather.city) is \(weather.temperature)°F.")
print("The temperature in \(weather.city) is \(weather.temperature)°F.")
print("The temperature in \(weather.city) is \(weather.temperature)°F.")

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

С CustomStringConvertible:

struct Weather: CustomStringConvertible {
   let city: String
   let temperature: Double

   var description: String {
         return "The temperature in \(city) is \(temperature)°F."
   }
}

let weather = Weather(city: "New York", temperature: 97.6)

print(weather) // The temperature in New York is 97.6°F.
print(weather) // The temperature in New York is 97.6°F.
print(weather) // The temperature in New York is 97.6°F.

Унаследовав протокол CustomStringConvertible, нам нужно предоставить значение для свойства description. Каждый раз, когда мы хотим использовать объект как строку, программа будет обращаться к свойству description. Теперь нам намного проще печатать и/или изменять наше сообщение с помощью этого удобного протокола :)

3. IteratorProtocol

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

Без IteratorProtocol:

let names = ["Bob", "Amy", "Mike"]
var currentIndex = 0

print("\(names[currentIndex]) did the laundry.")
currentIndex += 1

print("\(names[currentIndex]) did the dishes.")
currentIndex += 1

print("\(names[currentIndex]) did nothing.")

// Outputs
Bob did the laundry.
Amy did the dishes.
Mike did nothing.

С IteratorProtocol:

let names = ["Bob", "Amy", "Mike"]
var nameIterator = names.makeIterator()
print("\(nameIterator.next() ?? "") did the laundry.")

print("\(nameIterator.next() ?? "") did the dishes.")

print("\(nameIterator.next() ?? "") did nothing.")

// Outputs
Bob did the laundry.
Amy did the dishes.
Mike did nothing.

Функция makeIterator() возвращает объект, наследующий протокол IteratorProtocol. Мы можем использовать функцию next() для получения следующего значения без необходимости отслеживать текущий индекс. Помните, что функция next() возвращает необязательное значение.

Вывод

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

Источник

Exit mobile version