Быстрое и безболезненное знакомство с оболочками свойств Swift 5

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

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

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

Хорошо, давайте копнем!

Чтобы определить базовую оболочку свойств, создайте структуру, класс или перечисление и отметьте их с помощью атрибута @propertyWrapper:

@propertyWrapper
struct Box {
}

Оболочка свойств должна определять свойство с именем wrappedValue.

@propertyWrapper
struct Box {
    var wrappedValue: Int
}

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

    private var value = 0
    var wrappedValue: Int {
        get { value }
        set { value = newValue }
    }

Эта оболочка свойств пока не делает ничего значимого. Чтобы продемонстрировать его использование, давайте создадим структуру Foo:

struct Foo {

Затем объявите свойство x типа Int. Я применяю оболочку к этому свойству, записывая атрибут @Box перед именем свойства:

@Box var x: Int
}

Синтаксис короткий и приятный. За кулисами компилятор генерирует код для доступа к свойству через оболочку.

Мы можем создать экземпляр Foo и использовать его как обычно:

var t = Foo()
print(t.x)
// Prints: 0

Затем добавьте логику в код оболочки свойств. Я изменил геттер так, чтобы он возвращал только значения больше или равные 50:

@propertyWrapper
struct Box {
    private var value = 0
    var wrappedValue: Int {
        get { value > 50 ? value : 50 }
        set { value = newValue }
    }
}
var t = Foo()
print(t.x)
// Prints: 50

Реализация оболочки свойств, кодирующей свойства строки в кодировке Base64

Теперь, когда я показал вам, как создавать и использовать оболочку свойств, давайте реализуем кое-что полезное. Оболочка свойств Base64Encoded преобразует строку, которую она обертывает, в ее представление в кодировке Base64.

Установщик присваивает новое значение свойству частного значения. Получатель создает экземпляр Data из представления строки UTF8. Затем он выполняет кодирование Base64, вызывая метод экземпляра данных base64EncodedString ().

@propertyWrapper
struct Base64Encoded {
    private var value = “”
    var wrappedValue: String {
        get { Data(value.utf8).base64EncodedString() }
        set { value = newValue }
    }
}

Создайте новую структуру с именем Payload и примените оболочку к свойству text.

struct Payload {
    @Base64Encoded var text: String
}
var p = Payload()
p.text = “Property wrappers are awesome!”
print(p.text)

В том, как мы получаем доступ к текстовому экземпляру объекта Payload, нет ничего необычного. Однако свойство устанавливается и извлекается через оболочку свойств Base64Encoded. В выходных данных показана версия «Обертки свойств - это круто!» В кодировке Base64! нить:

UHJvcGVydHkgd3JhcHBlcnMgYXJlIGF3ZXNvbWUh

Вы можете проверить вывод с помощью онлайн-инструментов, таких как https://www.base64encoder.io.

Перейдите в мой репозиторий GitHub, чтобы загрузить полный исходный код: https://github.com/nyisztor/swift-features/blob/master/PropertyWrappers.swift

Property Wrappers - предложение: https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md

Резюме

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

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