Swift Academy · Lezione

Basi dei KeyPath

Tratti le proprietà come valori di prima classe.

Lezione 1 di 413 passaggi

Basi dei KeyPath è una lezione Swift Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Swift Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Swift Academy include 4 lezioni in totale.

Che cos'è un key path

Un key path è un valore che descrive il percorso verso una proprietà senza accedervi direttamente. Si può considerare come un riferimento memorizzato e riutilizzabile a quale proprietà si desidera, separato da quale istanza viene usata per leggerla.

Si scrive un key path con una barra rovesciata, il nome del tipo, un punto e il nome della proprietà. Swift assegna a questa espressione un valore KeyPath che è possibile passare come qualsiasi altro valore.

struct Person {
    let name: String
    let age: Int
}

let nameKeyPath = \Person.name
print(type(of: nameKeyPath))

Leggere un valore

Per leggere una proprietà tramite un key path, usate il subscript [keyPath:] su un'istanza. Passate il key path tra parentesi quadre e Swift restituisce il valore presente in quel percorso.

Questo è l'equivalente a runtime della scrittura diretta del nome della proprietà, ma ora la proprietà viene scelta in base ai dati invece di essere codificata direttamente nel codice.

struct Person {
    let name: String
    let age: Int
}

let alice = Person(name: "Alice", age: 30)
let path = \Person.name
print(alice[keyPath: path])

La sintassi dei key path nel dettaglio

La forma generale è il carattere di escape della barra rovesciata, seguito dal tipo radice, da un punto e dal nome della proprietà. La barra rovesciata segnala a Swift che si desidera un key path anziché il valore della proprietà.

Il tipo radice è il tipo da cui inizia il percorso. Il tipo risultato è il tipo della proprietà finale. Pertanto, un percorso da Person alla proprietà age ha come radice Person e come valore Int.

struct Person {
    let name: String
    let age: Int
}

let ageKeyPath: KeyPath<Person, Int> = \Person.age
let bob = Person(name: "Bob", age: 42)
print(bob[keyPath: ageKeyPath])

Concatenare proprietà annidate

I key path possono attraversare valori annidati. Se una proprietà è a sua volta una struct, è possibile continuare il percorso con un altro punto per raggiungere una proprietà più interna.

L'intera catena resta un singolo valore key path e i relativi tipi radice e risultato riflettono l'inizio e la fine della catena.

struct Address {
    let city: String
}
struct Person {
    let name: String
    let address: Address
}

let cityPath = \Person.address.city
let carol = Person(name: "Carol", address: Address(city: "Oslo"))
print(carol[keyPath: cityPath])

Memorizzare i key path nelle variabili

Poiché un key path è semplicemente un valore, è possibile memorizzarlo in una variabile, restituirlo da una funzione o conservare una raccolta di key path. Questo permette di decidere a runtime quale proprietà leggere.

In questo caso, scegliamo uno dei due key path memorizzati in base a un flag.

struct Person {
    let name: String
    let age: Int
}

let showAge = true
let chosen: PartialKeyPath<Person> = showAge ? \Person.age : \Person.name
let dave = Person(name: "Dave", age: 27)
print(dave[keyPath: chosen])

PartialKeyPath e AnyKeyPath

Swift dispone di una piccola famiglia di tipi di key path. KeyPath<Root, Value> conosce entrambi gli estremi. PartialKeyPath<Root> conosce la radice, ma cancella il tipo del valore. AnyKeyPath cancella entrambi.

Più informazioni sui tipi si conservano, più controlli il compilatore può eseguire al posto vostro. Ricorrete alle forme parziali o generiche solo quando avete davvero bisogno di combinare percorsi con tipi di valore diversi.

struct Person {
    let name: String
    let age: Int
}

let paths: [PartialKeyPath<Person>] = [\.name, \.age]
let eve = Person(name: "Eve", age: 19)
for p in paths {
    print(eve[keyPath: p])
}

Forma abbreviata in un tipo noto

Quando il tipo radice è già noto dal contesto, è possibile omettere il nome del tipo e scrivere soltanto la barra rovesciata, il punto e la proprietà. Il compilatore deduce la radice.

Questa forma abbreviata mantiene brevi i punti di chiamata, soprattutto nelle operazioni sulle raccolte in cui il tipo degli elementi è evidente.

struct Person {
    let name: String
    let age: Int
}

func value(of person: Person, at path: KeyPath<Person, Int>) -> Int {
    person[keyPath: path]
}

let frank = Person(name: "Frank", age: 55)
print(value(of: frank, at: \.age))

Key path come argomenti di funzione

Un modello comune consiste in una funzione generica che accetta un key path e lo applica a più istanze. In questo modo si separa che cosa leggere dalla logica che esegue la lettura.

Qui un helper generico estrae qualsiasi proprietà di qualsiasi tipo da un elenco di persone.

struct Person {
    let name: String
    let age: Int
}

func extract<T>(_ people: [Person], _ path: KeyPath<Person, T>) -> [T] {
    people.map { $0[keyPath: path] }
}

let people = [Person(name: "Ana", age: 21), Person(name: "Ben", age: 34)]
print(extract(people, \.name))
print(extract(people, \.age))

Key path e proprietà calcolate

I key path di sola lettura funzionano anche con le proprietà calcolate. Il percorso acquisisce il calcolo, quindi la lettura tramite quel percorso esegue il getter.

Questo significa che un key path non è limitato alle proprietà memorizzate: è idonea qualsiasi proprietà leggibile.

struct Rectangle {
    let width: Double
    let height: Double
    var area: Double { width * height }
}

let areaPath = \Rectangle.area
let r = Rectangle(width: 3, height: 4)
print(r[keyPath: areaPath])

Key path dell'identità

Esiste un key path speciale che fa riferimento all'intero valore stesso, scritto come una singola barra rovesciata seguita da un punto e da self. La lettura tramite questo percorso restituisce l'istanza invariata.

È utile quando un'API richiede un key path, ma si desidera l'elemento così com'è, ad esempio per ordinare i numeri in base a se stessi.

let numbers = [3, 1, 2]
let identity = \Int.self
for n in numbers {
    print(n[keyPath: identity])
}

Confrontare i key path

I key path sono Hashable ed Equatable. Due key path che puntano alla stessa proprietà dello stesso tipo sono uguali, quindi è possibile memorizzarli in set o usarli come chiavi di un dizionario.

Questo è utile per creare tabelle che associano una proprietà a un'etichetta o a un formatter.

struct Person {
    let name: String
    let age: Int
}

let labels: [PartialKeyPath<Person>: String] = [
    \Person.name: "Full Name",
    \Person.age: "Years Old"
]
print(labels[\Person.age] ?? "unknown")

Verifica rapida: leggere tramite key path

Verificate la vostra comprensione della lettura di una proprietà tramite un key path.

Riepilogo: nozioni di base sui key path

Avete appreso i fondamenti dei key path:

  • Un key path si scrive con una barra rovesciata, il tipo radice, un punto e il nome di una proprietà e descrive una proprietà senza leggerla.
  • Leggete un valore usando il subscript [keyPath:] su un'istanza.
  • I percorsi possono concatenarsi in proprietà annidate e indirizzare proprietà calcolate.
  • KeyPath, PartialKeyPath e AnyKeyPath sacrificano la sicurezza dei tipi in cambio di flessibilità.
  • I key path sono valori: potete memorizzarli, passarli, confrontarli e usarli come chiavi di un dizionario.

Successivamente userete i key path per rendere molto più concise le operazioni sulle raccolte.

struct Person {
    let name: String
    let age: Int
}

let path = \Person.age
let gina = Person(name: "Gina", age: 48)
print("Read via key path: \(gina[keyPath: path])")
Gratis per iniziare

Impara Swift con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
122
Lezioni
409

Domande Frequenti

La lezione «Basi dei KeyPath» è gratuita?

Sì — il testo completo di «Basi dei KeyPath» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Swift Academy, passa a CoddyKit PRO. Il corso Swift Academy include 4 lezioni in totale.

Cosa imparerò in «Basi dei KeyPath»?

Tratti le proprietà come valori di prima classe. Eserciti Swift Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Swift Academy?

Non è richiesta alcuna esperienza precedente. Swift Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Basi dei KeyPath»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Swift Academy?

Sì. Ogni lezione Swift Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Basi dei KeyPath
  2. Uso dei KeyPath nelle collezioni
  3. KeyPath scrivibili e di riferimento
  4. @dynamicMemberLookup
← Torna a Swift Academy