Swift Academy · Aula

Reutilização e restrições

Projete wrappers genéricos com restrições de tipo (por exemplo, Value: Comparable ), adicione APIs direcionadas usando where e componha vários wrappers.

Aula 2 de 38 etapas

Reutilização e restrições é uma aula grátis de Swift Academy no CoddyKit. Esta é a aula 2 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.

Por que usar restrições?

Escreva um envoltório e reutilize-o em vários tipos tornando-o genérico com restrições. Adicione APIs específicas com cláusulas where e componha pequenos envoltórios.

Genérico + Comparable

Use Comparable para fazer um Bounded funcionar com Int, String etc. Tipos inválidos são rejeitados no tempo de compilação.

@propertyWrapper
struct Bounded<Value: Comparable> {
    private var value: Value
    private let range: ClosedRange<Value>

    var wrappedValue: Value {
        get { value }
        set {
            // clamp using Comparable
            if newValue < range.lowerBound { value = range.lowerBound }
            else if newValue > range.upperBound { value = range.upperBound }
            else { value = newValue }
        }
    }

    init(wrappedValue: Value, _ range: ClosedRange<Value>) {
        self.range = range
        self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
    }
}

struct Stats {
    @Bounded(0...100) var score: Int = 120
    @Bounded("a"..."z") var letter: String = "Swift"
}
var st = Stats()
print(st.score)   // 100
st.letter = "m"
print(st.letter)

Extensões com restrições

Use where para oferecer recursos extras somente quando o tipo os aceitar (por exemplo, sinalizadores inteiros ou atualizações de ponto flutuante).

extension Bounded where Value: BinaryInteger {
    var isMaxed: Bool { wrappedValue == range.upperBound }
}
extension Bounded where Value: FloatingPoint {
    mutating func bump(by delta: Value) { wrappedValue = wrappedValue + delta }
}

struct Meter {
    @Bounded(0...10) var steps: Int = 9
    @Bounded(0.0...1.0) var progress: Double = 0.25
}
var m = Meter()
print(m.$steps)          // projectedValue not defined; accessing wrapper is not allowed directly here
print(m._steps)          // compiler creates backing storage name; shown for illustration only
print(m.steps)           // 9
print(m._progress)       // backing storage (illustrative)
m._progress.bump(by: 0.6)
print(m.progress)        // 0.85 (clamped if exceeded)

Envoltório apenas para coleções

Limite as APIs a coleções restringindo-as a RangeReplaceableCollection. Funciona com String e Array.

@propertyWrapper
struct MaxLength<Value: RangeReplaceableCollection> where Value.Element: Sendable {
    private var storage: Value
    private let limit: Int

    var wrappedValue: Value {
        get { storage }
        set {
            var v = newValue
            if v.count > limit { v.removeLast(v.count - limit) }
            storage = v
        }
    }

    init(wrappedValue: Value, _ limit: Int) {
        self.limit = limit
        self.storage = wrappedValue
        if storage.count > limit { storage.removeLast(storage.count - limit) }
    }
}

struct Post {
    @MaxLength(10) var title: String = "hello swift learners"
    @MaxLength(5) var tags: [String] = ["swift","ios","spm"]
}
var p = Post()
print(p.title)  // "hello swif"
print(p.tags)   // ["swift","ios","spm"]

Composição de envoltórios

Você pode empilhar pequenos envoltórios. Aqui, Trimmed é executado primeiro; depois, NonEmpty garante um valor alternativo.

@propertyWrapper
struct Trimmed {
    private var s: String = ""
    var wrappedValue: String {
        get { s }
        set { s = newValue.trimmingCharacters(in: .whitespacesAndNewlines) }
    }
    init(wrappedValue: String) { self.wrappedValue = wrappedValue }
}

@propertyWrapper
struct NonEmpty {
    private var s: String = ""
    var wrappedValue: String {
        get { s }
        set { s = newValue.isEmpty ? "N/A" : newValue }
    }
    init(wrappedValue: String) { self.wrappedValue = wrappedValue }
}

struct Profile {
    @NonEmpty @Trimmed var displayName: String = "  "
}
var prof = Profile()
print(prof.displayName)  // "N/A"

Variáveis locais + reutilização

Os envoltórios também funcionam com variáveis locais. Mantenha-os genéricos para reutilizá-los entre módulos.

@propertyWrapper
struct Default<Value> {
    private var value: Value
    private let make: () -> Value
    var wrappedValue: Value {
        get { value }
        set { value = newValue }
    }
    init(wrappedValue: Value, _ factory: @escaping () -> Value) {
        self.value = wrappedValue
        self.make = factory
    }
    mutating func reset() { value = make() }
}

// Local variable usage
do {
    @Default({ 0 }) var counter: Int = 5
    print(counter) // 5
    _counter.reset()
    print(counter) // 0
}

Restrição de compilação no envoltório

Verificação rápida: como restringir um envoltório a tipos Comparable?

Recapitulação

Recapitulação: torne os envoltórios genéricos, adicione restrições para manter o uso seguro, disponibilize APIs específicas com cláusulas where e componha pequenos envoltórios para obter clareza.

Grátis para começar

Aprenda Swift com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
122
Aulas
409

Perguntas Frequentes

A aula “Reutilização e restrições” é grátis?

Sim — o texto completo de “Reutilização e restrições” é 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 “Reutilização e restrições”?

Projete wrappers genéricos com restrições de tipo (por exemplo, Value: Comparable ), adicione APIs direcionadas usando where e componha vários wrappers. 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 2 de 3.

Quanto tempo leva a aula “Reutilização e restrições”?

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

  1. Criando wrappers, projectedValue
  2. Reutilização e restrições
  3. Padrões comuns de wrappers (validação, armazenamento em cache)
← Voltar para Swift Academy