0Pricing
Swift Academy · Pelajaran

Pola pembungkus umum (validasi, penyimpanan sementara)

Bangun pembungkus umum untuk validasi dan penyimpanan sementara : periksa masukan, sediakan nilai bawaan, memoisasikan pekerjaan yang mahal, serta tampilkan penanda pembantu melalui nilai proyeksi.

Pola pembungkus umum (validasi, penyimpanan sementara) adalah pelajaran Swift Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 3. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Swift Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Swift Academy mencakup 3 pelajaran total.

Yang akan kita bangun

Pelajaran ini membahas dua pola praktis:

  • Validasi: terima atau perbaiki masukan dengan nilai bawaan dan pesan.
  • Penembolokan: simpan hasil dan tampilkan pembantu seperti $helpers, misalnya clear() dan isCached.

Validasi: NonEmpty

@NonEmpty mencegah masukan kosong dan menyediakan nilai bawaan. projectedValue melaporkan apakah penetapan terakhir diperbaiki secara otomatis.

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

Validasi: berbasis aturan

@Validated bersifat generik dan menerima closure aturan serta nilai cadangan. Gunakan ini untuk pemeriksaan panjang, rentang, atau pemeriksaan khusus.

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

Penembolokan: memorisasi malas

@LazyCached menyimpan hasil secara memo dari suatu closure. $result menyediakan pembantu isCached dan 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)              // 1

Penembolokan: berbasis TTL

@TimedCache menyegarkan nilai setelah TTL berlalu. Nilai proyeksi dapat menyediakan age sehingga lokasi pemanggilan dapat menentukan kapan harus menyegarkannya.

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

Panduan desain

Tips desain:

  • Jaga agar validasi tetap murni dan mudah diprediksi; laporkan perbaikan melalui $flags.
  • Untuk penembolokan, jaga agar status tetap kecil; sediakan clear() atau isCached.
  • Utamakan argumen inisialisasi untuk kebijakan seperti nilai cadangan dan TTL.

Pembantu proyeksi untuk penembolokan

Pemeriksaan singkat: Apa yang seharusnya ditampilkan oleh $value dalam pembungkus penembolokan?

Ringkasan

Ringkasan: Gunakan pembungkus untuk memvalidasi masukan dengan nilai bawaan dan aturan, serta untuk menyimpan sementara hasil yang mahal dengan strategi malas atau TTL. Letakkan kontrol dan status di dalam projectedValue agar lokasi pemanggilan tetap bersih.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Pola pembungkus umum (validasi, penyimpanan sementara)” gratis?

Ya — teks lengkap “Pola pembungkus umum (validasi, penyimpanan sementara)” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Swift Academy, upgrade ke CoddyKit PRO. Kursus Swift Academy mencakup 3 pelajaran total.

Apa yang akan aku pelajari di “Pola pembungkus umum (validasi, penyimpanan sementara)”?

Bangun pembungkus umum untuk validasi dan penyimpanan sementara : periksa masukan, sediakan nilai bawaan, memoisasikan pekerjaan yang mahal, serta tampilkan penanda pembantu melalui nilai proyeksi. Kamu berlatih Swift Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Swift Academy?

Tidak diperlukan pengalaman sebelumnya. Swift Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 3.

Berapa lama pelajaran “Pola pembungkus umum (validasi, penyimpanan sementara)” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Swift Academy ini?

Ya. Setiap pelajaran Swift Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Membuat pembungkus, projectedValue
  2. Keterpakaian ulang dan batasan
  3. Pola pembungkus umum (validasi, penyimpanan sementara)
← Kembali ke Swift Academy