Geschiedenis van de vraag:
Opaque types (some) kwamen naar voren in Swift 5.1 en introduceerden een nieuwe manier om het retourtype van een functie of eigenschap te abstraheren, wanneer het type bekend is voor de compiler, maar verborgen blijft voor de gebruiker. Dit is een alternatief voor protocol existentials (any Protocol), maar met een strikte binding aan een specifiek type binnen de functie.
Probleem: Wanneer een functie een protocol met associatedtype retourneert (bijvoorbeeld, Sequence), kan je niet direct schrijven:
func makeNumberSequence() -> Sequence { ... } // fout
Protocol existentials stellen je in staat om elke implementatie te retourneren, maar garanderen niet hetzelfde type bij elke oproep:
func foo() -> any View { ... }
Dit leidt tot onvoorspelbaarheid en zwakke type veiligheid.
Oplossing: Gebruik opaque result type:
func makeNumbers() -> some Sequence { [1, 2, 3] }
Nu weet de compiler precies welk type er daadwerkelijk wordt geretourneerd, maar dit blijft verborgen voor buitenstaanders. Dit biedt prestatieoptimalisaties, veiligheid, stelt je in staat om SwiftUI DSL te gebruiken, en vergemakkelijkt het type-uitwisselen tussen modules.
Belangrijkste kenmerken:
Kunnen opaque types worden gebruikt om waarden op te slaan (zoals class properties)?
Nee. Opaque types worden alleen toegepast voor retourwaarden van functies of computed properties. Voor opslaan van waarden of arrays van waarden gebruik je existentials (any Protocol).
Kunnen verschillende takken van één functie verschillende types met some retourneren?
Nee. De compiler vereist dat beide (of alle) takken hetzelfde specifieke type retourneren, anders krijg je een fout:
func foo(flag: Bool) -> some Sequence { if flag { return [1, 2, 3] } else { return ["a", "b", "c"] // fout } }
Kan some worden gebruikt om het retourtype tussen meerdere functies te identificeren?
Nee. Elke functie met some retourneert haar unieke verborgen type, zelfs als dit feitelijk dezelfde array is. Het gebruik van de retourwaarde van één functie als parameter in een andere is niet toegestaan als beide some gebruiken met verschillende protocollen of verschillende verborgen types.
In een project wordt alles geretourneerd via any Protocol, collecties verliezen type-informatie, er ontstaan bugs bij downcasting, compile-tijd optimalisatie vertraagt.
Voordelen:
Nadelen:
In SwiftUI-ontwerp retourneren componenten some View, elk module definieert duidelijk het interne type. De bundelgrootte wordt verkleind, de build wordt versneld.
Voordelen:
Nadelen: