Swift Academy · leksjon

Betinget konvertering med as?

Prøv en konvertering som returnerer en optional ved feil.

Leksjon 2 av 413 trinn

Betinget konvertering med as? er en gratis leksjon i Swift Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Swift Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Swift Academy inneholder totalt 4 leksjoner.

Betinget typecasting

Operatoren for betinget typecasting, as?, forsøker en nedkasting og returnerer en optional: verdien pakket inn hvis det lykkes, eller nil hvis det mislykkes.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let maybe = a as? Dog
print(maybe != nil)

Resultatet er en optional

Fordi typecastingen kan mislykkes, er resultattypen Dog?, ikke Dog. De må pakke den ut før bruk.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let maybe: Dog? = a as? Dog
print(type(of: maybe))

Pakke ut med if let

Den idiomatiske måten å bruke as? på er i en if let-binding, som bare kjører blokken når typecastingen lykkes.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
if let dog = a as? Dog {
    print(dog.bark())
} else {
    print("Not a dog")
}

Mislykket typecasting returnerer nil

Når instansen ikke er måltypen, gir as? verdien nil, og blokken i if let hoppes over.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Cat(name: "Mia")
if let dog = a as? Dog {
    print(dog.bark())
} else {
    print("That is not a dog")
}

Kombinere med guard let

De kan også bruke guard let til å utføre typecastingen tidlig og avslutte hvis den mislykkes, slik at hovedflyten ikke får ekstra innrykk.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
func describe(_ a: Animal) {
    guard let cat = a as? Cat else {
        print("Not a cat")
        return
    }
    print(cat.meow())
}
describe(Cat(name: "Mia"))
describe(Dog(name: "Rex"))

Betinget typecasting i løkker

Å gå gjennom en blandet tabell og utføre betinget typecasting av hvert element er en ryddig måte å håndtere forskjellige underklasser på en trygg måte.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let zoo: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia"), Dog(name: "Buddy")]
for a in zoo {
    if let dog = a as? Dog {
        print(dog.bark())
    }
}

Typecasting til protokoller

as? kontrollerer også om en instans oppfyller en protokoll: den returnerer en verdi hvis instansen oppfyller protokollen, og ellers nil.

protocol Greeter { func greet() -> String }
class Person: Greeter { func greet() -> String { return "Hi" } }
class Rock {}
let items: [Any] = [Person(), Rock()]
for item in items {
    if let g = item as? Greeter { print(g.greet()) }
}

Nil-koalesering etter typecasting

De kan kombinere as? med operatoren ?? for å angi en reserveverdi når typecastingen mislykkes.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Cat(name: "Mia")
let sound = (a as? Dog)?.bark() ?? "unknown sound"
print(sound)

Kjede kall etter typecasting

Optional chaining lar Dem kalle en metode på resultatet av typecastingen. Hele uttrykket blir nil hvis typecastingen mislykkes.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let a: Animal = Dog(name: "Rex")
let bark = (a as? Dog)?.bark()
print(bark as Any)

Hvorfor betinget typecasting foretrekkes

as? fører aldri til en krasj; en mislykket typecasting gir ganske enkelt nil. Derfor er dette standardvalget for trygg nedkasting.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let unknown: Animal = Cat(name: "Mia")
let result = unknown as? Dog
print("Crashes? No. Value is nil:", result == nil)

Oppsummerende eksempel på betinget typecasting

Samlet i ett eksempel: Finn en undertype på en trygg måte, utfør handlingen på den, og håndter andre tilfeller på en ryddig måte.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
func sound(of a: Animal) -> String {
    if let d = a as? Dog { return d.bark() }
    if let c = a as? Cat { return c.meow() }
    return "silence"
}
print(sound(of: Dog(name: "Rex")))
print(sound(of: Cat(name: "Mia")))

Hurtigsjekk

Husk resultattypen for betinget typecasting.

Oppsummering: Betinget typecasting med as?

De har lært at as? utfører en trygg nedkasting og returnerer en optional, at if let og guard let pakker ut tilfellet der typecastingen lykkes, og at den aldri krasjer fordi en feil ganske enkelt gir nil. Derfor er dette den foretrukne operatoren for nedkasting.

class Animal {
    let name: String
    init(name: String) { self.name = name }
}
class Dog: Animal {
    func bark() -> String { return name + " says Woof" }
}
class Cat: Animal {
    func meow() -> String { return name + " says Meow" }
}
let pets: [Animal] = [Dog(name: "Rex"), Cat(name: "Mia")]
for p in pets {
    if let d = p as? Dog { print(d.bark()) } else if let c = p as? Cat { print(c.meow()) }
}
Gratis å komme i gang

Lær deg Swift med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
122
Leksjoner
409

Ofte stilte spørsmål

Er leksjonen «Betinget konvertering med as?» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Swift Academy, inkludert «Betinget konvertering med as?», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Swift Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Betinget konvertering med as?»?

Prøv en konvertering som returnerer en optional ved feil. Du øver på Swift Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Swift Academy?

Ingen tidligere erfaring er nødvendig. Swift Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.

Hvor lang tid tar leksjonen «Betinget konvertering med as?»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Swift Academy-leksjonen?

Ja. Alle Swift Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Grunnleggende opp- og nedkonvertering
  2. Betinget konvertering med as?
  3. Tvungen konvertering med as! og risikoene
  4. Kontrollere typer med is
← Tilbake til Swift Academy