KeyPaths in Swift e i suoi vantaggi

Apr 21 2023
KeyPath è un modo per fare riferimento a una proprietà o sottoproprietà specifica di un tipo, ad esempio una struttura o una classe. È come una scorciatoia o un riferimento a un particolare valore o proprietà all'interno di una struttura dati più ampia.

KeyPath è un modo per fare riferimento a una proprietà o sottoproprietà specifica di un tipo, ad esempio una struttura o una classe. È come una scorciatoia o un riferimento a un particolare valore o proprietà all'interno di una struttura dati più ampia.

In termini più semplici, i percorsi chiave in Swift sono come indicazioni che puntano a un'informazione specifica all'interno di una raccolta di dati più ampia. Semplificano l'accesso e la modifica di parti specifiche di tali dati senza dover cercare nell'intera raccolta.

Ad esempio, supponiamo che tu abbia una struttura chiamata Personcon le proprietà come name, agee address.

struct Address {
    let streetAddress: String
    let city: String
}

struct Person {
    let name: String
    var age: Int
    let address: Address
}

var person = Person(
               name: "John",
               age: 24,
               address: Address(
                 streetAddress: "2, qwerty",
                 city: "CA"
               )
             )

let nameKeyPath = \Person.name
let name = person[keyPath: nameKeyPath]
print(name) // John

let streetAddressKeyPath = \Person.address.streetAddress
print(person[keyPath: streetAddressKeyPath]) // 2, qwerty

Esistono due tipi di percorsi chiave: percorsi chiave scrivibili e di sola lettura.

  1. KeyPath di sola lettura:

2. Percorso chiave scrivibile:

Un percorso chiave scrivibile non solo consente di accedere a una proprietà o sottoproprietà di un tipo, ma anche di modificarne il valore. In termini più semplici, quando ci riferiamo a un tipo mutabile, diventa un percorso chiave di sola lettura. Se accediamo a una proprietà var, allora è un percorso chiave scrivibile.

let readOnlyKeyPath = \Person.name
print(type(of: readOnlyKeyPath)) // KeyPath<Person, String>

var writableKeyPath = \Person.age
print(type(of: writableKeyPath)) // WritableKeyPath<Person, Int>
person[keyPath: writableKeyPath] = 28 // 28

class Person {
    var age = 0
}

let referenceWritableKeyPath = \Person.age
print(type(of: referenceWritableKeyPath)) // ReferenceWritableKeyPath<Person3, Int>

Usi:

Esistono molti altri usi dei percorsi chiave in Swift e esploreremo alcuni esempi.

Nei metodi di raccolta Swift

In Swift, i keypath possono essere passati come argomenti a metodi come .mape .filter. Il compilatore convertirà il percorso chiave in una chiusura, consentendo un facile accesso e manipolazione degli elementi in una raccolta. Ad esempio, per estrarre i nomi delle persone da un array di Personoggetti, puoi utilizzare il .mapmetodo e passare un percorso chiave che fa riferimento alla nameproprietà del Persontipo, come mostrato di seguito:

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

let people = [
    Person(name: "Alice", age: 25),
    Person(name: "Bob", age: 30),
    Person(name: "Charlie", age: 35)
]

let names = people.map(\.name)
print(names) // prints ["Alice", "Bob", "Charlie"]

L'utilizzo dei percorsi chiave in questo modo può rendere il codice più conciso e leggibile, in quanto consente di accedere e manipolare proprietà specifiche degli oggetti senza dover scrivere una chiusura separata.

Creazione di un DSL (linguaggio specifico del dominio):

I KeyPath in Swift consentono di creare linguaggi specifici del dominio (DSL), mini-linguaggi per la risoluzione di problemi specifici all'interno di un dominio . Usando KeyPaths, possiamo creare una sintassi indipendente dai tipi per la creazione di predicati che filtrano le raccolte in base a criteri specifici.

Ad esempio, quando si filtra un array di oggetti Person, KeyPaths può aiutare a creare un DSL che esprima criteri basati sull'età in modo leggibile e indipendente dai tipi. Per esempio:

func > <T, V: Comparable>(lhs: KeyPath<T, V>, rhs: V) -> (T) -> Bool {
    return { $0[keyPath: lhs] > rhs }
}

let olderThan30 = people.filter(\.age > 30)

print(olderThan30) // prints "[Person(name: "Bob", age: 30), Person(name: "Charlie", age: 35)]"

Riepilogo:

I percorsi chiave in Swift consentono un facile accesso e modifica di valori specifici all'interno di strutture di dati complesse, migliorando l'espressività del codice e la sicurezza del tipo

I percorsi chiave possono essere molto potenti e flessibili e sono un concetto fondamentale in molte funzionalità avanzate di Swift.

Grazie per aver letto.

Saluti!

Seguici su Twitter e LinkedIn per ulteriori aggiornamenti.

# SwiftUI #S wift.org # evangelistapps #TheComposableArchitecture #swift #iOS #coding #iOS16