Pattern comuni per i wrapper (convalida, caching)
Crei wrapper comuni per la validation e il caching : verifichi l'input, fornisca valori predefiniti, memorizzi il risultato delle operazioni costose ed esponga flag di supporto tramite i valori proiettati.
Pattern comuni per i wrapper (convalida, caching) è una lezione Swift Academy gratuita su CoddyKit. Questa è la lezione 3 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.
Cosa costruiremo
Questa lezione mostra due modelli pratici:
- Validazione: accettare o correggere gli input con valori predefiniti e messaggi.
- Caching: memorizzare i risultati ed esporre tramite $helpers elementi come
clear()eisCached.
Validazione: NonEmpty
@NonEmpty impedisce gli input vuoti e fornisce un valore predefinito. projectedValue segnala se l'ultimo valore impostato è stato corretto automaticamente.
@propertyWrapper
struct NonEmpty {
private var value: String = ""
private(set) var lastFixed: Bool = false
var wrappedValue: String {
get { value }
set {
if newValue.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
value = "N/A" // default fallback
lastFixed = true
} else {
value = newValue
lastFixed = false
}
}
}
var projectedValue: Bool { lastFixed } // $name -> was fixed?
init(wrappedValue: String) { self.wrappedValue = wrappedValue }
}
struct Profile {
@NonEmpty var displayName: String = " "
}
var p = Profile()
print(p.displayName) // "N/A"
print(p.$displayName) // true (was fixed)Validazione basata su regole
@Validated è generico e accetta una closure di regola insieme a un valore di fallback. Lo utilizzi per controlli sulla lunghezza, sull'intervallo o personalizzati.
@propertyWrapper
struct Validated<Value> {
private var value: Value
private let rule: (Value) -> Bool
private let fallback: Value
private(set) var lastValid: Bool = true
var wrappedValue: Value {
get { value }
set {
if rule(newValue) {
value = newValue
lastValid = true
} else {
value = fallback
lastValid = false
}
}
}
var projectedValue: Bool { lastValid } // $prop -> is valid?
init(wrappedValue: Value, rule: @escaping (Value) -> Bool, fallback: Value) {
self.rule = rule
self.fallback = fallback
self.value = wrappedValue
self.lastValid = rule(wrappedValue)
if !lastValid { self.value = fallback }
}
}
struct Form {
@Validated(rule: { $0.count >= 3 }, fallback: "???")
var nickname: String = "hi"
}
var f = Form()
print(f.nickname) // "???" (invalid -> fallback)
print(f.$nickname) // falseCaching: memoizzazione lazy
@LazyCached memorizza in cache un valore ottenuto da una closure. $result espone gli helper isCached e clear().
@propertyWrapper
struct LazyCached<Value> {
private var storage: Value?
private let build: () -> Value
var wrappedValue: Value {
mutating get {
if let v = storage { return v } // hit
let v = build() // miss -> compute
storage = v
return v
}
// Optional: allow manual set to override cache
set { storage = newValue }
}
struct Controls {
private let getter: () -> Bool
private let clearer: () -> Void
var isCached: Bool { getter() }
func clear() { clearer() }
}
var projectedValue: Controls {
Controls(
getter: { self.storage != nil },
clearer: { self.storage = nil }
)
}
init(_ build: @escaping () -> Value) {
self.build = build
self.storage = nil
}
}
// Demo: expensive computation (simulated)
var calls = 0
func heavy() -> Int { calls += 1; return (1...10_000).reduce(0, +) }
struct Engine {
@LazyCached(heavy) var result: Int
}
var e = Engine()
print(e.$result.isCached) // false
print(e.result) // computes once
print(e.result) // uses cache
print(calls) // 1Caching basato sul TTL
@TimedCache aggiorna il valore dopo un TTL. Il valore proiettato può esporre age, così il codice chiamante può decidere quando aggiornare il valore.
@propertyWrapper
struct TimedCache<Value> {
private var storage: Value?
private var timestamp: Date?
private let ttl: TimeInterval
private let build: () -> Value
var wrappedValue: Value {
mutating get {
let now = Date()
if let t = timestamp, let v = storage, now.timeIntervalSince(t) < ttl {
return v // fresh
}
let v = build() // refresh
storage = v
timestamp = now
return v
}
}
struct Status { let age: TimeInterval? }
var projectedValue: Status {
let age = timestamp.map { Date().timeIntervalSince($0) }
return Status(age: age)
}
init(ttl: TimeInterval, _ build: @escaping () -> Value) {
self.ttl = ttl
self.build = build
}
}
// Demo (age only; TTL behavior depends on real time)
struct Stats {
@TimedCache(ttl: 60) { Int.random(in: 0...1000) } var score: Int
}
var s2 = Stats()
print(s2.score) // computes
print(s2.$score.age ?? -1)Linee guida di progettazione
Suggerimenti di progettazione:
- Mantenga la validazione pura e prevedibile; segnali le correzioni con $flags.
- Per il caching, mantenga ridotto lo stato e fornisca clear() o isCached.
- Preferisca gli argomenti di init per le policy, come fallback e TTL.
Helper proiettati per il caching
Verifica rapida: che cosa dovrebbe esporre $value in un wrapper di caching?
Riepilogo
Riepilogo: utilizzi i wrapper per validare gli input, con valori predefiniti e regole, e per memorizzare in cache risultati costosi, con caricamento lazy o TTL. Inserisca il controllo e lo stato in projectedValue per mantenere pulito il codice chiamante.
Domande Frequenti
La lezione «Pattern comuni per i wrapper (convalida, caching)» è gratuita?
Sì — il testo completo di «Pattern comuni per i wrapper (convalida, caching)» è 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 «Pattern comuni per i wrapper (convalida, caching)»?
Crei wrapper comuni per la validation e il caching : verifichi l'input, fornisca valori predefiniti, memorizzi il risultato delle operazioni costose ed esponga flag di supporto tramite i valori proie… 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 3 di 3.
Quanto tempo richiede la lezione «Pattern comuni per i wrapper (convalida, caching)»?
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)