Wrapper di proprietà in Swift
Cos'è "Property Wrapper"?
Dalla guida del linguaggio di programmazione Swift , A Property Wrapper è definito come di seguito:
Un wrapper di proprietà aggiunge un livello di separazione tra il codice che gestisce la modalità di archiviazione di una proprietà e il codice che definisce una proprietà.
Come suggerisce il nome, un wrapper di proprietà è un tipo che avvolge una proprietà nella nuova logica. In termini più semplici, un wrapper di proprietà è una caratteristica del linguaggio rapido che consente di definire un tipo personalizzato per implementare il comportamento dal metodo `getter` e `setter` e riutilizzarlo.
È usato per decorare le proprietà nella tua classe, struct o enum. Aiuta a ridurre il codice boilerplate e migliora la leggibilità.
Quando dovresti usare Property Wrapper?
Prendiamo l'esempio seguente di struct Student che restituisce e stampa il nome in maiuscolo.
struct Student {
var firstName: String
var lastName: String
}
- Osservatori di proprietà
- Proprietà calcolate
struct Student {
var firstName: String {
didSet {
firstName = firstName.uppercased()
}
}
var lastName: String {
didSet {
lastName = lastName.uppercased()
}
}
init(firstName: String, lastName: String) {
self.firstName = firstName.uppercased()
self.lastName = lastName.uppercased()
}
}
struct Student {
private var _firstName: String = ""
var firstName: String {
set {
_firstName = newValue.uppercased()
}
get {
return _firstName
}
}
private var _lastName: String = ""
var lastName: String {
set {
_lastName = newValue.uppercased()
}
get {
return _lastName
}
}
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
}
Come creare un wrapper di proprietà personalizzato?
Per definire un wrapper di proprietà, dobbiamo decorare la classe, lo struct o il tipo enum con la parola chiave @PropertyWrapper e quindi dobbiamo implementare una proprietà chiamata wrapperValue in esso.
Common consente di creare un nuovo tipo chiamato osservatore di proprietà AllCaps per restituire sempre il nome in maiuscolo.
Approccio degli osservatori di proprietà:
@propertyWrapper
struct AllCaps {
var wrappedValue: String {
didSet {
wrappedValue = wrappedValue.uppercased()
}
}
init(wrappedValue: String) {
self.wrappedValue = wrappedValue.uppercased()
}
}
Sulla dichiarazione di proprietà, dobbiamo decorare la proprietà con la parola chiave @AllCaps che è un osservatore di proprietà. Abbiamo solo bisogno di aggiungere la parola chiave @AllCaps alle proprietà che restituiscono la proprietà in lettere maiuscole.
@AllCaps var name: String = "Steve Jobs"
In questo approccio all'osservatore di proprietà, dobbiamo applicare la logica in init perché gli osservatori didSet non vengono chiamati quando la proprietà viene inizializzata per la prima volta, quindi dobbiamo aggiungere la logica in init .
Quindi useremo un approccio alternativo alla proprietà calcolata nel wrapper della proprietà.
Approccio di proprietà calcolata:
In questo approccio, stiamo applicando la logica solo nel getter invece di applicarla due volte come l'approccio dell'osservatore di proprietà.
Esempio 1:
@propertyWrapper
struct AllCaps {
private var name: String
var wrappedValue: String {
set {
name = newValue
}
get {
return name.uppercased()
}
}
init(wrappedValue: String) {
self.name = wrappedValue
}
}
// usage
struct Student {
@AllCaps var firstName: String
@AllCaps var lastName: String
}
var student = Student(firstName: "Steve", lastName: "Jobs")
print("Hello \(student.firstName) \(student.lastName)")
// output:
Hello STEVE JOBS
Aggiungiamo un'altra proprietà in student chiamata score che è sempre nell'intervallo tra 0 e 100. Quindi creeremo un altro wrapper di proprietà chiamato InRange che consentirà alla proprietà di essere compresa tra 0 e 100.
@propertyWrapper struct InRange {
private var mark: Int
var wrappedValue: Int {
set {
mark = newValue
}
get {
return max(0, min(mark, 100))
}
}
init(wrappedValue: Int) {
mark = wrappedValue
}
}
struct Student {
@InRange var mark: Int
}
let student1 = Student(mark: 75)
print(student1.mark)
// output:
75
let student2 = Student(mark: 110)
print(student2.mark)
// output:
100
let student3 = Student(mark: -20)
print(student3.mark)
// output:
0
Esistono numerosi punti in cui possiamo utilizzare un wrapper di proprietà per evitare il duplicato come impostazioni predefinite utente, threading, cambio di orientamento, variabili pigre ecc.,
Nel prossimo articolo, discuteremo un'altra proprietà nel Property Wrapper chiamata Valore proiettato.
Grazie per aver letto!
Seguici su Twitter @evangelistsw

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































