Swift Academy · Oppitunti

Kirjoitettavat ja viittaavat KeyPathit

Lue ja kirjoita key pathien kautta.

Oppitunti 3/413 vaihetta

Kirjoitettavat ja viittaavat KeyPathit on ilmainen Swift Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Swift Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Swift Academy-kurssilla on yhteensä 4 oppituntia.

Vain luku -avainpolut ja kirjoitettavat avainpolut

Tavallisella KeyPath-avainpolulla voi vain lukea arvon. Avainpolun kautta kirjoittamiseen tarvitaan kirjoitettava muunnelma. Swiftissä niitä on kaksi: yksi arvotyypeille ja toinen viitetyypeille.

Tässä oppitunnissa käsitellään rakenteille tarkoitettua WritableKeyPath-tyyppiä, luokille tarkoitettua ReferenceWritableKeyPath-tyyppiä sekä sitä, miten [keyPath:]-alaindeksistä tulee asetettava.

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

let writable: WritableKeyPath<Person, Int> = \Person.age
print(type(of: writable))

WritableKeyPath arvotyypeille

WritableKeyPath kohdistuu arvotyypin muokattavaan tallennettuun ominaisuuteen. Sen kautta asettamista varten myös instanssin itsensä on oltava var, koska rakenteen ominaisuuden muuttaminen muuttaa koko arvoa.

Kirjoittakaa arvo käyttämällä [keyPath:]-alaindeksiä sijoituksen vasemmalla puolella.

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)

Miksi instanssin on oltava var

Arvotyypeillä avainpolun kautta kirjoittaminen muuttaa kopiota paikallaan. Jos instanssi on let, mitään muutettavaa ei ole, joten sijoitus ei käänny.

Sääntö vastaa tavallista ominaisuuden muuttamista: rakenteen tallennetun ominaisuuden voi asettaa vain, kun rakenne on muuttujassa.

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)

Geneerinen asetusapufunktio

Koska kirjoitettava avainpolku sisältää tiedon muutettavasta ominaisuudesta, voitte kirjoittaa geneerisen funktion, joka päivittää minkä tahansa arvotyypin mitä tahansa ominaisuutta. Välittäkää instanssi inout-parametrina, jotta muutos kirjoitetaan takaisin.

Tämä muodostaa pienten funktionaalisten päivitysapuohjelmien perustan.

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 luokille

Luokkia varten Swift tarjoaa ReferenceWritableKeyPath-tyypin. Koska luokan instanssi on viite, voitte kirjoittaa sen kautta, vaikka instanssi olisi tallennettu let-vakioon; viite ei muutu, ainoastaan sen osoittama olio muuttuu.

Tämä on keskeinen ero arvotyyppien kirjoitettaviin avainpolkuihin.

class Counter {
    var value: Int = 0
}

let counter = Counter()
let path: ReferenceWritableKeyPath<Counter, Int> = \Counter.value
counter[keyPath: path] = 5
print(counter.value)

let-viite, muokattava olio

Huomatkaa, että alla oleva luokan instanssi on let, mutta voimme silti asettaa sen ominaisuuden avainpolun kautta. Rakenteen kanssa tämä aiheuttaisi käännösvirheen.

Syynä on se, että luokan ominaisuuden muuttaminen ei edellytä viitteen olevan muokattava, vaan ainoastaan itse ominaisuuden.

class Profile {
    var nickname: String = ""
}

let profile = Profile()
let nickPath = \Profile.nickname
profile[keyPath: nickPath] = "Ace"
print(profile.nickname)

Avainpolkujen tyyppihierarkia

Kirjoitettavat avainpolkutyypit muodostavat hierarkian. ReferenceWritableKeyPath on WritableKeyPath-tyypin alityyppi, joka puolestaan on KeyPath-tyypin alityyppi. Siksi tarkempaa avainpolkutyyppiä voidaan käyttää kaikkialla, missä odotetaan yleisempää tyyppiä.

Voitte siis välittää ReferenceWritableKeyPath-tyypin funktiolle, joka tarvitsee vain lukemiseen käytettävän KeyPath-tyypin.

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

Sisäkkäisten arvotyyppien päivittäminen

Kirjoitettavat avainpolut ketjuuntuvat sisäkkäisten rakenteiden läpi. Syvällä sijaitsevan ominaisuuden asettaminen kirjoittaa kaikki ympäröivät arvot ketjussa uudelleen yhdellä sijoituksella.

Tässä muutamme sisäkkäisen osoitteen kaupungin.

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)

Useiden päivitysten toteuttaminen

Koska kirjoitettavat avainpolut ovat arvoja, voitte tallentaa päivitysluettelon avainpolku- ja arvopareina ja käsitellä sitä silmukassa. Tämä on pieni korjausjärjestelmä.

Tässä teemme kaksi muutosta asetusrakenteeseen.

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)

Sidontatyylinen konfigurointi

Yleinen käytännön sovellus on konfigurointiapufunktio, joka asettaa ominaisuuden juuri luotuun olioon ja palauttaa sen, mikä mahdollistaa ketjutettavan tyylin. Luokkien kanssa tämä toimii myös let-tulokselle.

Tässä asetamme selitteen tekstin kirjoitettavan viiteavainpolun kautta.

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)

Oikean avainpolkutyypin valitseminen

Käyttäkää KeyPath-tyyppiä, kun vain luette arvoja, WritableKeyPath-tyyppiä, kun asetatte var-muuttujaan tallennetun arvotyypin ominaisuuden, ja ReferenceWritableKeyPath-tyyppiä, kun asetatte luokan ominaisuuden myös let-vakion kautta.

Sopivimman mahdollisen tyypin valitseminen pitää rajapintanne selkeinä sen suhteen, luetaanko vai muutetaanko arvoja.

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

Pikakertaus: kirjoitettavat avainpolut

Muistakaa, mikä avainpolkutyyppi mahdollistaa luokan ominaisuuden asettamisen, vaikka instanssi olisi let-vakio.

Kertaus: kirjoitettavat ja viiteavainpolut

Opitte kirjoittamaan avainpolkujen kautta:

  • WritableKeyPath asettaa arvotyypin tallennetun ominaisuuden, ja instanssin on oltava var.
  • ReferenceWritableKeyPath asettaa luokan ominaisuuden ja toimii myös let-vakion kautta.
  • [keyPath:]-alaindeksi esiintyy sijoituksen vasemmalla puolella, kun arvoa kirjoitetaan.
  • Tyypit muodostavat hierarkian, joten kirjoitettavaa avainpolkua voidaan käyttää vain lukuun tarkoitetun avainpolun sijasta.
  • Geneeriset inout-asetusfunktiot ja konfigurointiapufunktiot rakentuvat näiden varaan.

Seuraavaksi näette @dynamicMemberLookup-määritteen, joka käyttää avainpolkuja tarjotakseen piste-merkinnällä tapahtuvan pääsyn dynaamisiin tietoihin.

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)")
Aloita maksutta

Opi Swift tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
122
Oppitunnit
409

Usein kysytyt kysymykset

Onko oppitunti ”Kirjoitettavat ja viittaavat KeyPathit” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Swift Academy-oppimispolun 3 oppituntia, myös oppitunnin “Kirjoitettavat ja viittaavat KeyPathit”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Swift Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Kirjoitettavat ja viittaavat KeyPathit”?

Lue ja kirjoita key pathien kautta. Harjoittelet Swift Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Swift Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Swift Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Kirjoitettavat ja viittaavat KeyPathit”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Swift Academy-oppitunnilla?

Kyllä. Jokainen Swift Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. KeyPathin perusteet
  2. KeyPathien käyttö kokoelmissa
  3. Kirjoitettavat ja viittaavat KeyPathit
  4. @dynamicMemberLookup
← Takaisin: Swift Academy