Warunkowe rzutowanie za pomocą as?
Próba rzutowania zwracającego optional w razie niepowodzenia.
Warunkowe rzutowanie za pomocą as? to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.
Rzutowanie warunkowe
Operator rzutowania warunkowego as? próbuje wykonać rzutowanie w dół i zwraca opcję: opakowaną wartość, jeśli operacja się powiedzie, albo nil, jeśli się nie powiedzie.
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)Wynik jest opcją
Ponieważ rzutowanie może się nie powieść, typem wyniku jest Dog?, a nie Dog. Przed użyciem należy rozpakować opcję.
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))Rozpakowywanie za pomocą if let
Idiomatycznym sposobem użycia as? jest umieszczenie go w wiązaniu if let, którego ciało zostanie wykonane tylko wtedy, gdy rzutowanie się powiedzie.
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")
}Nieudane rzutowanie zwraca nil
Jeśli instancja nie jest typu docelowego, as? zwraca nil, a ciało if let zostaje pominię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 a: Animal = Cat(name: "Mia")
if let dog = a as? Dog {
print(dog.bark())
} else {
print("That is not a dog")
}Łączenie z guard let
Można również użyć guard let, aby wykonać rzutowanie na początku i zakończyć działanie, jeśli się ono nie powiedzie. Dzięki temu główna ścieżka kodu nie wymaga dodatkowego wcięcia.
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"))Rzutowanie warunkowe w pętlach
Iterowanie po mieszanej tablicy i warunkowe rzutowanie każdego elementu to przejrzysty sposób bezpiecznej obsługi różnych podklas.
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())
}
}Rzutowanie do protokołów
as? sprawdza również zgodność z protokołem: zwraca wartość, jeśli instancja jest zgodna z protokołem, a w przeciwnym razie 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()) }
}Operator ?? po rzutowaniu
Operator as? można połączyć z operatorem ??, aby podać wartość zastępczą, gdy rzutowanie się nie powiedzie.
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)Łączenie wywołań metod po rzutowaniu
Łańcuchowe wywołania opcjonalne pozwalają wywołać metodę na wyniku rzutowania; całe wyrażenie ma wartość nil, jeśli rzutowanie się nie powiedzie.
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)Dlaczego preferuje się rzutowanie warunkowe
as? nigdy nie powoduje awarii; nieudane rzutowanie po prostu daje nil. Dzięki temu jest bezpieślnym wyborem domyślnym przy rzutowaniu w dół.
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)Przykład podsumowujący rzutowania warunkowego
Łącząc wszystkie elementy: należy bezpiecznie wykryć podtyp, wykonać na nim odpowiednią operację, a w przeciwnym razie łagodnie obsłużyć sytuację zastępczą.
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")))Szybkie sprawdzenie
Proszę przypomnieć sobie typ wyniku rzutowania warunkowego.
Podsumowanie: rzutowanie warunkowe za pomocą as?
Dowiedział się Pan / Dowiedziała się Pani, że as? wykonuje bezpieczne rzutowanie w dół i zwraca opcję, że if let i guard let rozpakowują pomyślnie uzyskaną wartość, a także że operator ten nigdy nie powoduje awarii, ponieważ niepowodzenie zwraca po prostu nil, dzięki czemu jest preferowanym operatorem rzutowania w dół.
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()) }
}Ucz się Swift dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 122
- Lekcje
- 409
Często zadawane pytania
Czy lekcja „Warunkowe rzutowanie za pomocą as?” jest bezpłatna?
Tak — pełny tekst „Warunkowe rzutowanie za pomocą as?” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Warunkowe rzutowanie za pomocą as?”?
Próba rzutowania zwracającego optional w razie niepowodzenia. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Swift Academy?
Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Warunkowe rzutowanie za pomocą as?”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?
Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Podstawy rzutowania w górę i w dół
- Warunkowe rzutowanie za pomocą as?
- Wymuszone rzutowanie za pomocą as! i jego zagrożenia
- Sprawdzanie typów za pomocą is