Das Schlüsselwort `some` in Swift und SwiftUI: Wozu wird es benötigt?

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Das geheimnisvolle „some“: Warum fragen Tausende von Entwicklern danach?

\n\n

Wenn Sie jemals in SwiftUI programmiert haben, ist Ihnen sicherlich die Konstruktion some View begegnet. Sie sieht einfach aus, aber Anfänger sind oft verwirrt: „Was ist dieses ‚some‘? Warum kann ich nicht einfach View schreiben? Und wenn ich some entferne – geht es dann kaputt?“. Die Frage „What is the "some" keyword in Swift(UI)?“ hat auf Stack Overflow tausende Aufrufe gesammelt – und das ist kein Zufall. Hinter einem kurzen Wort verbirgt sich eine ganze Philosophie des modernen Swift.

\n\n

In diesem Artikel werden wir verstehen, was das Schlüsselwort some ist, warum es in der Sprache eingeführt wurde und warum SwiftUI ohne es undenkbar ist. Sie erfahren, wie es mit Generics, Protokollen und „opaque types“ zusammenhängt. Und vor allem – Sie werden verstehen, wie Sie saubereren und leistungsfähigeren Code schreiben können.

\n\n

Das Problem, das „some“ löst

\n\n

Stellen Sie sich vor, Sie schreiben eine Funktion, die ein Objekt zurückgibt, das dem Protokoll View entspricht. In SwiftUI passiert das ständig:

\n\n
func makeGreeting() -> View {\n    return Text("Hello!")\n}
\n\n

Der Swift-Compiler wird sagen: „Das Protokoll 'View' kann nur als generische Einschränkung (generic constraint) verwendet werden, weil es Self- oder associated type-Anforderungen hat.“ Das klingt beängstigend, aber der Kern ist einfach: Das Protokoll View in SwiftUI erfordert, dass der Typ zur Kompilierzeit bekannt ist. Wenn wir View zurückgeben – ist das eine Abstraktion, aber der Compiler benötigt Konkretes.

\n\n

Früher behalfen sich Entwickler mit Generics:

\n\n
func makeGreeting<T: View>() -> T {\n    return Text("Hello!") as! T\n}
\n\n

Das funktionierte, sah aber wie ein Workaround aus: Sie versprechen dem Compiler, dass Sie T zurückgeben, aber in Wirklichkeit „tun Sie nur so“. Außerdem musste der aufrufende Code den Typ explizit angeben. Unschön und unsicher.

\n\n

„Some“ – der Retter vor Boilerplate-Code

\n\n

Das Schlüsselwort some wurde in Swift in Version 5.1 genau für solche Fälle eingeführt. Es sagt dem Compiler: „Ich werde einen konkreten Typ zurückgeben, der dem Protokoll entspricht, aber ich möchte seinen Namen nicht nennen. Du bestimmst ihn selbst zur Kompilierzeit.“ Dies nennt man einen opaque type.

\n\n

Kehren wir zu unserem Beispiel zurück:

\n\n
func makeGreeting() -> some View {\n    return Text("Hello!")\n}
\n\n

Jetzt kompiliert der Code! Der Compiler weiß, dass genau Text zurückgegeben wird, aber von außen sehen wir nur some View. Dies bringt zwei Vorteile:

\n
    \n
  • Typsicherheit – der Compiler überprüft, dass der Rückgabetyp immer derselbe ist.
  • \n
  • Kapselung – wir verbergen Implementierungsdetails vor dem aufrufenden Code.
  • \n
\n\n

Vergleich: „some“ vs. Generics vs. Protokolle

\n\n

Um die Magie von some besser zu verstehen, vergleichen wir die drei Ansätze anhand eines konkreten Beispiels. Nehmen wir an, wir möchten eine Funktion schreiben, die eine Form (Kreis oder Quadrat) zurückgibt.

\n\n

1. Rückgabe eines Protokolls (wird nicht kompilieren)

\n\n
protocol Shape {\n    func draw()\n}\n\nstruct Circle: Shape {\n    func draw() { print("Zeichne Kreis") }\n}\nstruct Square: Shape {\n    func draw() { print("Zeichne Quadrat") }\n}\n\n// Fehler: Das Protokoll 'Shape' kann nicht als Rückgabetyp verwendet werden\nfunc makeShape() -> Shape {\n    return Circle()\n}
\n\n

Wie wir bereits wissen – das funktioniert nicht, wenn das Protokoll associated types oder Self-Anforderungen hat.

\n\n

2. Verwendung von Generics

\n\n
func makeShape<T: Shape>() -> T {\n    // Wir müssen irgendwie T erstellen, aber wir kennen den konkreten Typ nicht\n    fatalError("Kann Generic nicht erstellen")\n}
\n\n

Problem: Der aufrufende Code muss wissen, welchen Typ er erwarten soll. Die Funktion kann nicht selbst entscheiden, was sie zurückgibt.

\n\n

3. Verwendung von „some“ (funktioniert perfekt)

\n\n
func makeShape() -> some Shape {\n                

Blogs

Buchempfehlungen