Swift Academy · Pelajaran

@dynamicMemberLookup

Bangun akses anggota yang dinamis dan aman terhadap tipe.

Pelajaran 4 dari 413 langkah

@dynamicMemberLookup adalah pelajaran Swift Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. 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 4 pelajaran total.

Apa Itu Pencarian Anggota Dinamis?

Atribut @dynamicMemberLookup memungkinkan suatu tipe merespons akses anggota dengan sintaks titik yang tidak dideklarasikan sebagai properti nyata. Ketika Anda menulis value.something, Swift meneruskannya ke subskrip khusus yang Anda definisikan.

Hal ini membuat tipe pembungkus terasa alami, sekaligus menjaga akses tersebut tetap terpusat.

@dynamicMemberLookup
struct Settings {
    private var storage: [String: String] = ["theme": "dark"]
    subscript(dynamicMember key: String) -> String? {
        storage[key]
    }
}

let s = Settings()
print(s.theme ?? "none")

Subskrip yang Diperlukan

Tipe yang ditandai dengan @dynamicMemberLookup harus mengimplementasikan subscript(dynamicMember:). Ketika parameternya berupa String, nama anggota yang Anda ketik akan menjadi teks tersebut saat program berjalan.

Jadi, config.timeout memanggil subskrip dengan kunci "timeout".

@dynamicMemberLookup
struct Config {
    let values: [String: Int]
    subscript(dynamicMember member: String) -> Int {
        values[member] ?? 0
    }
}

let config = Config(values: ["timeout": 30, "retries": 3])
print(config.timeout)
print(config.retries)

Pencarian Berbasis Teks Tidak Aman bagi Tipe

Pencarian anggota dinamis berbasis teks memang fleksibel, tetapi menghilangkan pemeriksaan saat kompilasi. Jika Anda salah mengeja nama anggota, kode tetap berhasil dikompilasi dan Anda mendapatkan apa pun yang dikembalikan subskrip untuk kunci yang tidak ditemukan.

Di bawah ini, anggota yang tidak dikenal secara diam-diam mengembalikan nilai bawaan, bukan gagal dikompilasi.

@dynamicMemberLookup
struct Config {
    let values: [String: Int]
    subscript(dynamicMember member: String) -> Int {
        values[member] ?? -1
    }
}

let config = Config(values: ["timeout": 30])
print(config.tmout)

Pencarian Aman bagi Tipe dengan Jalur Kunci

Untuk keamanan, Anda dapat membuat subskrip menerima KeyPath, bukan teks. Kini kompiler memverifikasi bahwa anggota tersebut ada pada tipe yang dibungkus, sehingga pemeriksaan penuh kembali tersedia dan akses tetap dapat diteruskan.

Pola ini ideal untuk tipe pembungkus yang menyimpan nilai bertipe kuat.

struct User { let name: String; let age: Int }

@dynamicMemberLookup
struct Boxed {
    let user: User
    subscript<T>(dynamicMember path: KeyPath<User, T>) -> T {
        user[keyPath: path]
    }
}

let boxed = Boxed(user: User(name: "Ada", age: 36))
print(boxed.name)
print(boxed.age)

Mengapa Versi Jalur Kunci Lebih Aman

Karena subskrip menerima KeyPath<User, T>, hanya anggota yang benar-benar ada pada User yang diizinkan. Salah ketik seperti boxed.naem kini akan gagal dikompilasi, tidak seperti versi berbasis teks.

Anda mendapatkan kemudahan sintaks titik tanpa risiko tersebut.

struct User { let name: String; let age: Int }

@dynamicMemberLookup
struct ReadOnly {
    let value: User
    subscript<T>(dynamicMember path: KeyPath<User, T>) -> T {
        value[keyPath: path]
    }
}

let r = ReadOnly(value: User(name: "Lin", age: 22))
print(r.name, r.age)

Anggota Dinamis yang Dapat Ditulis

Jika subskrip menyediakan penyetel dan menerima WritableKeyPath, Anda juga dapat menetapkan nilai ke anggota yang diteruskan. Pembungkus tersebut meneruskan penulisan langsung ke nilai yang dibungkus.

Dengan demikian, Anda mendapatkan pembungkus transparan yang dapat diubah.

struct Profile { var name: String; var score: Int }

@dynamicMemberLookup
struct Wrapper {
    var value: Profile
    subscript<T>(dynamicMember path: WritableKeyPath<Profile, T>) -> T {
        get { value[keyPath: path] }
        set { value[keyPath: path] = newValue }
    }
}

var w = Wrapper(value: Profile(name: "Mo", score: 0))
w.score = 99
print(w.value.score)

Meneruskan ke Objek yang Dibungkus

Pencarian anggota dinamis sangat berguna untuk proksi ringan yang sebagian besar meneruskan akses ke nilai di dalamnya, tetapi menambahkan sedikit perilaku. Subskrip tersebut menjaga logika penerusan tetap terpusat.

Di sini pembungkus pencatatan meneruskan pembacaan dan menampilkan anggota yang diakses.

struct Account { let id: Int; let balance: Double }

@dynamicMemberLookup
struct Logged {
    let account: Account
    subscript<T>(dynamicMember path: KeyPath<Account, T>) -> T {
        let result = account[keyPath: path]
        print("accessed a member")
        return result
    }
}

let logged = Logged(account: Account(id: 7, balance: 100))
print(logged.balance)

Menggabungkannya dengan Gagasan Pemanggilan Dinamis

Pencarian anggota dinamis berpadu dengan baik dengan tipe generik. Satu subskrip generik dapat meneruskan properti dengan tipe apa pun, sehingga satu pembungkus dapat digunakan untuk nilai dengan berbagai bentuk.

Di sini Proxy yang sama dapat digunakan baik ketika anggotanya berupa teks maupun bilangan bulat.

struct Item { let title: String; let count: Int }

@dynamicMemberLookup
struct Proxy<Wrapped> {
    let wrapped: Wrapped
    subscript<T>(dynamicMember path: KeyPath<Wrapped, T>) -> T {
        wrapped[keyPath: path]
    }
}

let proxy = Proxy(wrapped: Item(title: "Book", count: 4))
print(proxy.title, proxy.count)

Pencarian Berbasis Teks untuk Data Mirip JSON

Bentuk berbasis teks tetap memiliki kegunaan: untuk merepresentasikan data yang strukturnya longgar, seperti JSON yang diuraikan, ketika anggota belum diketahui saat kompilasi. Setiap akses menjadi pencarian dalam kamus.

Di sini sebuah nilai kecil mirip JSON menyediakan propertinya melalui sintaks titik.

@dynamicMemberLookup
struct JSON {
    let fields: [String: String]
    subscript(dynamicMember key: String) -> String {
        fields[key] ?? ""
    }
}

let json = JSON(fields: ["city": "Oslo", "country": "Norway"])
print(json.city)
print(json.country)

Keterbatasan yang Perlu Diingat

Pencarian anggota dinamis hanya memengaruhi sintaks akses anggota; fitur ini tidak menambahkan properti tersimpan yang nyata. Alat bantu seperti pelengkapan otomatis berfungsi untuk bentuk jalur kunci, tetapi tidak untuk kunci teks sembarang.

Utamakan versi jalur kunci setiap kali bentuk data yang mendasarinya sudah diketahui, dan gunakan versi berbasis teks hanya untuk data yang benar-benar dinamis.

struct Point { let x: Int; let y: Int }

@dynamicMemberLookup
struct Safe {
    let point: Point
    subscript<T>(dynamicMember path: KeyPath<Point, T>) -> T {
        point[keyPath: path]
    }
}

let safe = Safe(point: Point(x: 3, y: 4))
print(safe.x + safe.y)

Dekorator Praktis

Dengan menggabungkan semuanya, berikut adalah pembungkus terukur yang meneruskan setiap pembacaan properti ke nilai di dalamnya sambil menghitung jumlah akses. Kerangka kerja nyata menggunakan gagasan ini untuk observasi dan pelacakan.

Sintaks titik pada pembungkus terasa sama persis seperti ketika Anda menggunakan nilainya secara langsung.

struct Sensor { let temperature: Double; let humidity: Double }

@dynamicMemberLookup
class Tracked {
    let sensor: Sensor
    var reads = 0
    init(_ s: Sensor) { sensor = s }
    subscript<T>(dynamicMember path: KeyPath<Sensor, T>) -> T {
        reads += 1
        return sensor[keyPath: path]
    }
}

let t = Tracked(Sensor(temperature: 21.5, humidity: 0.4))
print(t.temperature)
print(t.humidity)
print(t.reads)

Pemeriksaan Singkat: Pencarian Dinamis yang Aman bagi Tipe

Ingatlah parameter subskrip yang membuat pencarian anggota dinamis aman bagi tipe.

Ringkasan: Pencarian Anggota Dinamis

Anda telah mempelajari cara kerja @dynamicMemberLookup:

  • Atribut tersebut mengarahkan akses sintaks titik yang tidak dideklarasikan ke subscript(dynamicMember:).
  • Parameter String memberikan akses yang fleksibel tetapi tidak diperiksa, ideal untuk data seperti JSON.
  • Parameter KeyPath mengembalikan keamanan tipe penuh dan pelengkapan otomatis.
  • WritableKeyPath dengan penyetel memungkinkan Anda meneruskan penulisan melalui pembungkus.
  • Ini adalah kemudahan sintaks yang secara alami cocok dengan pola proksi dan dekorator.

Sekarang Anda memiliki perangkat key path yang lengkap: membaca, menulis, menggunakan koleksi, dan meneruskan akses secara dinamis.

struct User { let name: String }

@dynamicMemberLookup
struct Wrap {
    let user: User
    subscript<T>(dynamicMember path: KeyPath<User, T>) -> T {
        user[keyPath: path]
    }
}

print(Wrap(user: User(name: "Final")).name)
Gratis untuk memulai

Belajar Swift dengan tutor AI — gratis

Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.

Kursus
122
Pelajaran
409

Pertanyaan yang Sering Diajukan

Apakah pelajaran “@dynamicMemberLookup” gratis?

Ya — teks lengkap “@dynamicMemberLookup” 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 4 pelajaran total.

Apa yang akan aku pelajari di “@dynamicMemberLookup”?

Bangun akses anggota yang dinamis dan aman terhadap tipe. 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 4 dari 4.

Berapa lama pelajaran “@dynamicMemberLookup” 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. Dasar-Dasar KeyPath
  2. Menggunakan KeyPaths dalam Koleksi
  3. KeyPath yang Dapat Ditulis dan Referensi
  4. @dynamicMemberLookup
← Kembali ke Swift Academy