Padrões comuns de wrappers (validação, armazenamento em cache)
Crie wrappers comuns de validação e armazenamento em cache : valide a entrada, forneça valores padrão, memorize operações dispendiosas e disponibilize sinalizadores auxiliares por meio de valores projetados.
Padrões comuns de wrappers (validação, armazenamento em cache) é uma aula grátis de Swift Academy no CoddyKit. Esta é a aula 3 de 3. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Swift Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Swift Academy inclui 3 aulas no total.
O que vamos construir
Esta lição apresenta dois padrões práticos:
- Validação: aceite ou corrija entradas usando valores padrão e mensagens.
- Armazenamento em cache: armazene resultados e disponibilize $helpers como
clear()eisCached.
Validação: NonEmpty
@NonEmpty impede entradas vazias e fornece um valor padrão. O projectedValue informa se o último valor definido foi corrigido 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)Validação: baseada em regras
@Validated é genérico e aceita um fechamento de regra e um valor alternativo. Use-o para verificações de comprimento, intervalo ou personalizadas.
@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) // falseArmazenamento em cache: memorização preguiçosa
@LazyCached memoriza um valor obtido de um fechamento. $result disponibiliza os auxiliares 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) // 1Armazenamento em cache: baseado em TTL
@TimedCache atualiza o valor após um TTL. O valor projetado pode disponibilizar age, permitindo que os pontos de chamada decidam quando atualizar.
@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)Diretrizes de projeto
Dicas de projeto:
- Mantenha a validação pura e previsível; informe as correções com $flags.
- Para o armazenamento em cache, mantenha o estado pequeno; forneça clear() ou isCached.
- Prefira argumentos de init para políticas (valores alternativos, TTL).
Auxiliares projetados para armazenamento em cache
Verificação rápida: o que $value deve disponibilizar em um envoltório de armazenamento em cache?
Recapitulação
Recapitulação: use envoltórios para validar entradas (valores padrão, regras) e para armazenar em cache resultados dispendiosos (memorização preguiçosa, TTL). Coloque o controle e o status em projectedValue para obter pontos de chamada limpos.
Perguntas Frequentes
A aula “Padrões comuns de wrappers (validação, armazenamento em cache)” é grátis?
Sim — o texto completo de “Padrões comuns de wrappers (validação, armazenamento em cache)” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Swift Academy, atualize para CoddyKit PRO. O curso de Swift Academy inclui 3 aulas no total.
O que vou aprender em “Padrões comuns de wrappers (validação, armazenamento em cache)”?
Crie wrappers comuns de validação e armazenamento em cache : valide a entrada, forneça valores padrão, memorize operações dispendiosas e disponibilize sinalizadores auxiliares por meio de valores pro… Você pratica Swift Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Swift Academy?
Nenhuma experiência prévia é necessária. Swift Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 3.
Quanto tempo leva a aula “Padrões comuns de wrappers (validação, armazenamento em cache)”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Swift Academy?
Sim. Cada aula de Swift Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Criando wrappers, projectedValue
- Reutilização e restrições
- Padrões comuns de wrappers (validação, armazenamento em cache)