Creare wrapper, projectedValue
Crei un wrapper personalizzato, configuri wrappedValue ed esponga metadati/helper con projectedValue ( $ ).
Creare wrapper, projectedValue è una lezione Swift Academy gratuita su CoddyKit. Questa è la lezione 1 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Swift Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Swift Academy include 3 lezioni in totale.
Perché usare i property wrapper?
Un property wrapper è un tipo riutilizzabile che gestisce il modo in cui una proprietà viene memorizzata e letta:
- wrappedValue: il valore pubblico
- projectedValue: un'API aggiuntiva tramite
$ - Configurazione tramite inizializzatori/argomenti
Clamped e flag proiettato
@Clamped limita un numero a un intervallo. Il projectedValue ($hp) indica se l'ultima assegnazione ha applicato il limite.
@propertyWrapper
struct Clamped {
private var value: Int
private let range: ClosedRange<Int>
private(set) var wasClampedLastSet = false
var wrappedValue: Int {
get { value }
set {
let clamped = min(max(newValue, range.lowerBound), range.upperBound)
wasClampedLastSet = (clamped != newValue)
value = clamped
}
}
var projectedValue: Bool { wasClampedLastSet } // $prop -> was it clamped?
init(wrappedValue: Int, range: ClosedRange<Int>) {
self.range = range
let clamped = min(max(wrappedValue, range.lowerBound), range.upperBound)
self.value = clamped
self.wasClampedLastSet = (clamped != wrappedValue)
}
}
struct Player {
@Clamped(range: 0...100) var hp: Int = 120 // init clamps to 100
}
var p = Player()
print(p.hp) // 100
p.hp = -5
print(p.hp, p.$hp) // 0 true (was clamped)Normalizzazione e vista alternativa
I wrapper possono trasformare l'input (trim/lowercase). $property può esporre una comoda forma alternativa.
@propertyWrapper
struct Normalized {
private var storage: String = ""
var wrappedValue: String {
get { storage }
set { storage = newValue.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() }
}
var projectedValue: String { storage.uppercased() } // alternate view
init(wrappedValue: String) { self.wrappedValue = wrappedValue }
}
struct User {
@Normalized var username: String = " Alice "
}
let u = User()
print(u.username) // "alice"
print(u.$username) // "ALICE" (projected)Property wrapper configurabile
Passi gli argomenti ai wrapper (ad esempio length). Il wrapper applica la formattazione ogni volta che imposta la proprietà.
@propertyWrapper
struct Padded {
private var value: String
private let length: Int
var wrappedValue: String {
get { value }
set {
let s = newValue
value = s.count >= length ? String(s.prefix(length))
: s + String(repeating: " ", count: length - s.count)
}
}
var projectedValue: Int { value.count } // current width
init(wrappedValue: String, length: Int) {
self.length = length
self.value = ""
self.wrappedValue = wrappedValue
}
}
struct Row {
@Padded(length: 6) var code: String = "AB"
}
var r = Row()
print("|\(r.code)|") // |AB |
print(r.$code) // 6Cronologia tramite $value
Usi projectedValue per esporre metadati come la cronologia delle modifiche senza appesantire l'API del valore principale.
@propertyWrapper
struct History<Value> {
private var value: Value
private(set) var changes: [Value] = []
var wrappedValue: Value {
get { value }
set { changes.append(value); value = newValue }
}
var projectedValue: [Value] { changes } // $prop -> previous values
init(wrappedValue: Value) { self.value = wrappedValue }
}
struct Settings {
@History var level: Int = 1
}
var s = Settings()
s.level = 2
s.level = 3
print(s.level) // 3
print(s.$level) // [1, 2]Linee guida di progettazione
Suggerimenti:
- Mantenga i wrapper piccoli e focalizzati.
- Documenti ciò che espone $projectedValue.
- Preferisca trasformazioni pure; eviti effetti collaterali pesanti.
- Fornisca inizializzatori chiari e valori predefiniti sensati.
Scopo del valore proiettato
Verifica rapida: a che cosa serve $property nei wrapper?
Riepilogo
Riepilogo: implementi @propertyWrapper con un wrappedValue; esponga helper, flag e cronologia tramite projectedValue ($) e configuri il comportamento tramite inizializzatori.
Domande Frequenti
La lezione «Creare wrapper, projectedValue» è gratuita?
Sì — il testo completo di «Creare wrapper, projectedValue» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Swift Academy, passa a CoddyKit PRO. Il corso Swift Academy include 3 lezioni in totale.
Cosa imparerò in «Creare wrapper, projectedValue»?
Crei un wrapper personalizzato, configuri wrappedValue ed esponga metadati/helper con projectedValue ( $ ). Eserciti Swift Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Swift Academy?
Non è richiesta alcuna esperienza precedente. Swift Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 3.
Quanto tempo richiede la lezione «Creare wrapper, projectedValue»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Swift Academy?
Sì. Ogni lezione Swift Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Creare wrapper, projectedValue
- Riutilizzabilità e vincoli
- Pattern comuni per i wrapper (convalida, caching)