KeyPaths accessibles en écriture et de référence
Lisez et écrivez par l’intermédiaire de chemins de clés.
KeyPaths accessibles en écriture et de référence est une leçon Swift Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Swift Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Swift Academy comprend 4 leçons au total.
Chemins de clés en lecture seule et modifiables
Un simple KeyPath permet uniquement de lire une valeur. Pour écrire au moyen d'un chemin de clé, vous avez besoin d'une variante accessible en écriture. Swift en propose deux : l'une pour les types valeur et l'autre pour les types référence.
Cette leçon présente WritableKeyPath pour les structures et ReferenceWritableKeyPath pour les classes, ainsi que la manière dont le sous-script [keyPath:] devient accessible en écriture.
struct Person {
var name: String
var age: Int
}
let writable: WritableKeyPath<Person, Int> = \Person.age
print(type(of: writable))WritableKeyPath pour les types valeur
Un WritableKeyPath cible une propriété stockée modifiable d'un type valeur. Pour écrire au moyen de ce chemin, l'instance elle-même doit être une var, car modifier une propriété de structure modifie toute la valeur.
Utilisez le sous-script [keyPath:] à gauche d'une affectation pour écrire.
struct Person {
var name: String
var age: Int
}
var alice = Person(name: "Alice", age: 30)
let agePath = \Person.age
alice[keyPath: agePath] = 31
print(alice.age)Pourquoi l'instance doit être une var
Pour les types valeur, écrire au moyen d'un chemin de clé modifie une copie sur place. Si l'instance est une let, il n'y a rien à modifier et l'affectation ne compilera pas.
Cette règle correspond à la modification habituelle d'une propriété : vous ne pouvez définir la propriété stockée d'une structure que lorsque celle-ci est contenue dans une variable.
struct Point {
var x: Int
var y: Int
}
var p = Point(x: 1, y: 2)
p[keyPath: \Point.x] = 10
p[keyPath: \Point.y] = 20
print(p)Une fonction générique d'affectation
Comme un chemin de clé accessible en écriture mémorise la propriété à modifier, vous pouvez écrire une fonction générique qui met à jour n'importe quelle propriété de n'importe quel type valeur. Passez l'instance avec inout afin que la modification soit répercutée.
C'est le fondement de petits utilitaires de mise à jour fonctionnelle.
func update<Root, Value>(_ root: inout Root, _ path: WritableKeyPath<Root, Value>, to value: Value) {
root[keyPath: path] = value
}
struct Person { var name: String; var age: Int }
var bob = Person(name: "Bob", age: 40)
update(&bob, \.age, to: 41)
print(bob.age)ReferenceWritableKeyPath pour les classes
Pour les classes, Swift fournit ReferenceWritableKeyPath. Comme une instance de classe est une référence, vous pouvez écrire au moyen de celle-ci même lorsque l'instance est conservée dans une constante let ; la référence ne change pas, seul l'objet vers lequel elle pointe est modifié.
C'est la différence essentielle avec les chemins de clés accessibles en écriture des types valeur.
class Counter {
var value: Int = 0
}
let counter = Counter()
let path: ReferenceWritableKeyPath<Counter, Int> = \Counter.value
counter[keyPath: path] = 5
print(counter.value)Référence constante, objet modifiable
Remarquez que l'instance de classe ci-dessous est une let, et que nous pouvons pourtant définir sa propriété au moyen du chemin de clé. Avec une structure, cela provoquerait une erreur de compilation.
C'est parce que modifier une propriété de classe ne nécessite pas que la référence soit modifiable, mais seulement que la propriété le soit.
class Profile {
var nickname: String = ""
}
let profile = Profile()
let nickPath = \Profile.nickname
profile[keyPath: nickPath] = "Ace"
print(profile.nickname)La hiérarchie des types de chemins de clés
Les types de chemins de clés accessibles en écriture forment une hiérarchie. ReferenceWritableKeyPath est un sous-type de WritableKeyPath, qui est lui-même un sous-type de KeyPath. Un chemin de clé plus spécifique peut donc être utilisé partout où un chemin plus général est attendu.
Vous pouvez ainsi transmettre un ReferenceWritableKeyPath à une fonction qui a seulement besoin de lire au moyen d'un KeyPath.
class Box { var size: Int = 1 }
func readSize(_ box: Box, _ path: KeyPath<Box, Int>) -> Int {
box[keyPath: path]
}
let writable: ReferenceWritableKeyPath<Box, Int> = \Box.size
print(readSize(Box(), writable))Mettre à jour des types valeur imbriqués
Les chemins de clés accessibles en écriture s'enchaînent à travers les structures imbriquées. La définition d'une propriété profondément imbriquée réécrit chaque valeur qui l'englobe en remontant la chaîne, le tout en une seule affectation.
Ici, nous modifions city à l'intérieur d'une structure imbriquée.
struct Address { var city: String }
struct Person { var name: String; var address: Address }
var carol = Person(name: "Carol", address: Address(city: "Oslo"))
carol[keyPath: \Person.address.city] = "Bergen"
print(carol.address.city)Appliquer plusieurs mises à jour
Comme les chemins de clés accessibles en écriture sont des valeurs, vous pouvez stocker une liste de mises à jour sous forme de paires chemin de clé-valeur et les appliquer dans une boucle. C'est un petit système de correctifs.
Ici, nous appliquons deux modifications à une structure settings.
struct Settings { var volume: Int; var brightness: Int }
var settings = Settings(volume: 5, brightness: 5)
func apply(_ s: inout Settings, _ path: WritableKeyPath<Settings, Int>, _ v: Int) {
s[keyPath: path] = v
}
apply(&settings, \.volume, 8)
apply(&settings, \.brightness, 3)
print(settings)Configuration de type liaison
Un cas d'utilisation courant dans le monde réel consiste à utiliser une fonction configure qui définit une propriété sur un objet fraîchement créé, puis le renvoie, ce qui permet un style fluide. Avec les classes, cela fonctionne sur un résultat let.
Ici, nous définissons le texte d'un label au moyen d'un chemin de clé modifiable par référence.
class Label { var text: String = "" }
func configure<T: AnyObject, V>(_ object: T, _ path: ReferenceWritableKeyPath<T, V>, _ value: V) -> T {
object[keyPath: path] = value
return object
}
let label = configure(Label(), \.text, "Hello")
print(label.text)Choisir le type de chemin de clé approprié
Utilisez KeyPath lorsque vous faites uniquement une lecture, WritableKeyPath pour définir une propriété d'un type valeur stocké dans une var, et ReferenceWritableKeyPath pour définir une propriété de classe même au travers d'une let.
Choisir le type le plus spécifique qui convient permet à vos interfaces de décrire honnêtement si elles lisent ou modifient les données.
struct S { var n: Int }
class C { var n: Int = 0 }
let read: KeyPath<S, Int> = \S.n
let writeStruct: WritableKeyPath<S, Int> = \S.n
let writeClass: ReferenceWritableKeyPath<C, Int> = \C.n
print(type(of: read), type(of: writeStruct), type(of: writeClass))Vérification rapide : chemins de clés accessibles en écriture
Rappelez-vous quel type de chemin de clé permet de définir une propriété de classe même lorsque l'instance est une constante.
Récapitulatif : chemins de clés modifiables et par référence
Vous avez appris à écrire au moyen des chemins de clés :
WritableKeyPathdéfinit une propriété stockée d'un type valeur et nécessite une instancevar.ReferenceWritableKeyPathdéfinit une propriété de classe et fonctionne même au travers d'unelet.- Le sous-script
[keyPath:]apparaît à gauche d'une affectation pour permettre l'écriture. - Les types forment une hiérarchie, de sorte qu'un chemin de clé accessible en écriture peut remplacer un chemin en lecture seule.
- Les fonctions génériques d'affectation avec
inoutet les fonctions configure s'appuient sur ces éléments.
Vous allez maintenant découvrir @dynamicMemberLookup, qui utilise les chemins de clés pour proposer un accès avec la notation pointée aux données dynamiques.
struct Person { var name: String; var age: Int }
var dave = Person(name: "Dave", age: 27)
dave[keyPath: \Person.age] = 28
print("Updated age: \(dave.age)")Questions Fréquemment Posées
La leçon « KeyPaths accessibles en écriture et de référence » est-elle gratuite ?
Oui — le texte complet de « KeyPaths accessibles en écriture et de référence » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Swift Academy, passe à CoddyKit PRO. Le cours Swift Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « KeyPaths accessibles en écriture et de référence » ?
Lisez et écrivez par l’intermédiaire de chemins de clés. Tu pratiques Swift Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Swift Academy ?
Aucune expérience préalable n'est requise. Swift Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « KeyPaths accessibles en écriture et de référence » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Swift Academy ?
Oui. Chaque leçon Swift Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Bases de KeyPath
- Utiliser KeyPaths dans les collections
- KeyPaths accessibles en écriture et de référence
- @dynamicMemberLookup