0Pricing
Swift Academy · Lekcja

Existentials z any i wymazywanie typu

Używanie any Protocol, koszt wydajności oraz sytuacje, w których lepiej wybrać generyki.

Existentials z any i wymazywanie typu to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 3 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.

Czym jest typ egzystencjalny?

Typ egzystencjalny opakowuje dowolną wartość zgodną z protokołem za jednolitym interfejsem, a rozstrzygnięcie następuje w czasie wykonywania.

protocol Drawable { func draw() }
struct Line: Drawable { func draw() { print("Line") } }
let d: any Drawable = Line()
d.draw()

Słowo kluczowe any

Swift 5.7 wymaga słowa kluczowego any przed nazwami protokołów używanymi jako typy egzystencjalne, aby jawnie wskazać opakowanie.

func render(_ shape: any Drawable) {
  shape.draw()
}
render(Line())

Koszt typów egzystencjalnych

Typy egzystencjalne korzystają z alokacji na stercie i dynamicznego wywoływania, co może być wolniejsze niż typy generyczne z wywoływaniem statycznym.

// Existential – dynamic dispatch, potential heap alloc
var shapes: [any Drawable] = [Line(), Line()]
// Generic – static dispatch, no boxing
func drawGeneric<T: Drawable>(_ s: T) { s.draw() }

Problem PAT-ów i typów egzystencjalnych

Protokoły z typami skojarzonymi (PAT) nie mogą być używane jako nieograniczone typy egzystencjalne bez wymazywania typu.

protocol Container { associatedtype Item }
// var c: any Container // Swift 5.7 allows with "any" but loses Item info

Wzorzec wymazywania typu

Wrapper wymazujący typ opakowuje konkretny typ w strukturę, ukrywając jego konkretną reprezentację.

struct AnyDrawable: Drawable {
  private let _draw: () -> Void
  init<D: Drawable>(_ d: D) { _draw = d.draw }
  func draw() { _draw() }
}

AnySequence i AnyPublisher

Biblioteka standardowa Swift i Combine dostarczają wrappery wymazujące typ, takie jak AnySequence i AnyPublisher.

import Combine
let subject = PassthroughSubject<Int, Never>()
let pub: AnyPublisher<Int, Never> = subject.eraseToAnyPublisher()

eraseToAnyPublisher()

eraseToAnyPublisher() ukrywa konkretny łańcuch publishera, dzięki czemu kod wywołujący zależy wyłącznie od AnyPublisher.

func fetch() -> AnyPublisher<String, Error> {
  URLSession.shared.dataTaskPublisher(for: URL(string: "https://example.com")!)
    .map { String(data: $0.data, encoding: .utf8) ?? "" }
    .eraseToAnyPublisher()
}

Kiedy typy egzystencjalne są właściwym wyborem

Należy używać typów egzystencjalnych w przypadku niejednorodnych kolekcji lub gdy dokładny typ nie jest znany podczas kompilacji.

var widgets: [any Drawable] = [] // mixed concrete types OK

Preferowanie generyków zamiast typów egzystencjalnych

Jeśli to możliwe, należy zastępować typy egzystencjalne generykami, aby uzyskać statyczne wywoływanie i lepszą wydajność.

// Prefer this:
func draw<T: Drawable>(_ item: T) { item.draw() }
// Over this:
func draw(_ item: any Drawable) { item.draw() }

Otwieranie typów egzystencjalnych

Swift 5.7+ może „otworzyć” typ egzystencjalny podczas wywoływania funkcji generycznej, automatycznie wydobywając typ bazowy.

func drawGeneric<T: Drawable>(_ d: T) { d.draw() }
let d: any Drawable = Line()
drawGeneric(d) // compiler opens the existential automatically

Wymazywanie typu a typy opaque

Wymazywanie typu ukrywa typ na potrzeby użycia z typami niejednorodnymi, natomiast typy opaque zachowują tożsamość dla jednego spójnego typu zwracanego.

let erased: any Drawable = Line()   // runtime type unknown
let opaque: some Drawable = Line()   // compile-time fixed type

Szybkie sprawdzenie

Jaki jest główny koszt wydajnościowy typów egzystencjalnych?

Podsumowanie lekcji

Typy egzystencjalne (any Protocol) umożliwiają polimorfizm w czasie wykonywania kosztem dynamicznego wywoływania. Wymazywanie typu opakowuje konkretne typy za stabilnym interfejsem. Dla wydajności należy preferować generyki, a typów egzystencjalnych używać w przypadku niejednorodnych kolekcji.

Często zadawane pytania

Czy lekcja „Existentials z any i wymazywanie typu” jest bezpłatna?

Tak — pełny tekst „Existentials z any i wymazywanie typu” 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 „Existentials z any i wymazywanie typu”?

Używanie any Protocol, koszt wydajności oraz sytuacje, w których lepiej wybrać generyki. Ć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 3 z 4.

Ile czasu zajmuje lekcja „Existentials z any i wymazywanie typu”?

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

  1. Ograniczenia generyczne i klauzule where
  2. Typy niejawne ze słowem kluczowym some
  3. Existentials z any i wymazywanie typu
  4. Główne typy powiązane i typowane błędy
← Powrót do Swift Academy