0Pricing
Swift Academy · Lección

Crear wrappers, projectedValue

Cree un wrapper personalizado, configure wrappedValue y exponga metadatos/helpers con projectedValue ( $ ).

Crear wrappers, projectedValue es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 1 de 3. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 3 lecciones en total.

¿Por qué usar envoltorios de propiedades?

Un envoltorio de propiedades es un tipo reutilizable que gestiona cómo se almacena o se lee una propiedad:

  • wrappedValue: el valor público
  • projectedValue: API adicional mediante $
  • Configuración mediante inicializadores/argumentos

Indicador proyectado y límite

@Clamped limita un número a un intervalo. El projectedValue ($hp) indica si el último valor asignado fue limitado.

@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)

Normalización y vista alternativa

Los envoltorios pueden transformar la entrada (quitar espacios/convertir a minúsculas). $property puede exponer una forma alternativa práctica.

@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)

Envoltorio configurable

Pase argumentos a los envoltorios (por ejemplo, length). El envoltorio aplica el formato cada vez que establece la propiedad.

@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)        // 6

Historial mediante $value

Use projectedValue para exponer metadatos, como un historial de cambios, sin sobrecargar la API del valor principal.

@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]

Directrices de diseño

Consejos:

  • Mantenga los envoltorios pequeños y enfocados.
  • Documente qué expone $projectedValue.
  • Prefiera transformaciones puras; evite efectos secundarios costosos.
  • Proporcione inicializadores claros y valores predeterminados razonables.

Propósito del valor proyectado

Comprobación rápida: ¿Para qué se usa $property en los envoltorios?

Resumen

Resumen: Implemente @propertyWrapper con un wrappedValue; exponga auxiliares, indicadores e historiales mediante projectedValue ($) y configure el comportamiento mediante inicializadores.

Preguntas frecuentes

¿La lección «Crear wrappers, projectedValue» es gratis?

Sí — el texto completo de «Crear wrappers, projectedValue» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 3 lecciones en total.

¿Qué aprenderé en «Crear wrappers, projectedValue»?

Cree un wrapper personalizado, configure wrappedValue y exponga metadatos/helpers con projectedValue ( $ ). Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Swift Academy?

No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 3.

¿Cuánto tiempo toma la lección «Crear wrappers, projectedValue»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Swift Academy?

Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Crear wrappers, projectedValue
  2. Reutilización y restricciones
  3. Patrones comunes de wrappers (validación, caché)
← Volver a Swift Academy