Kurz: Ein struct gruppiert Daten und Methoden. Structs sind Werttypen: Zuweisen kopiert.
Teil des Kurses Swift
Struct: Werttyp
Ein struct gruppiert Daten und Methoden. Structs sind Werttypen: Zuweisen kopiert.
struct Punkt {
var x: Double
var y: Double = 0 // Standardwert
var abstand: Double { (x * x + y * y).squareRoot() } // berechnete Eigenschaft
mutating func verschiebe(dx: Double, dy: Double) { // mutating: ändert self
x += dx; y += dy
}
static let ursprung = Punkt(x: 0)
func beschreibung() -> String { "(\(x), \(y))" }
}
var a = Punkt(x: 3, y: 4)
var b = a // Kopie!
b.verschiebe(dx: 1, dy: 1)
print(a.beschreibung(), b.beschreibung(), a.abstand, Punkt.ursprung.x)
struct Konto {
private(set) var stand: Double = 0
let inhaber: String
var historie: [Double] = []
mutating func einzahlen(_ betrag: Double) {
guard betrag > 0 else { return }
stand += betrag
historie.append(betrag)
}
init(inhaber: String, startstand: Double = 0) {
self.inhaber = inhaber
self.stand = startstand
}
}
var k = Konto(inhaber: "Mia", startstand: 100)
k.einzahlen(50); k.einzahlen(-5)
print(k.inhaber, k.stand, k.historie)Ausgabe:
(3.0, 4.0) (4.0, 5.0) 5.0 0.0
Mia 150.0 [50.0]Klassen: Referenztyp
Eine class ist ein Referenztyp: Mehrere Variablen zeigen auf dasselbe Objekt. Klassen unterstützen Vererbung.
class Tier {
let name: String
init(name: String) { self.name = name }
func laut() -> String { "..." }
func vorstellen() -> String { "\(name) sagt \(laut())" }
}
class Hund: Tier {
override func laut() -> String { "Wuff" }
func apportiere() -> String { "\(name) holt den Ball" }
}
class Katze: Tier {
var leben = 9
override func laut() -> String { "Miau" }
override func vorstellen() -> String { super.vorstellen() + " (\(leben) Leben)" }
}
let tiere: [Tier] = [Hund(name: "Rex"), Katze(name: "Mimi")]
for t in tiere { print(t.vorstellen()) }
if let h = tiere[0] as? Hund { print(h.apportiere()) }
print(tiere[1] is Katze)
let eins = Katze(name: "A")
let zwei = eins // gleiche Instanz
zwei.leben = 3
print(eins.leben, eins === zwei)
class Zaehler {
var wert = 0
deinit { print("Zähler freigegeben") }
}
do { let z = Zaehler(); z.wert = 5 }Ausgabe:
Rex sagt Wuff
Mimi sagt Miau (9 Leben)
Rex holt den Ball
true
3 true
Zähler freigegeben| struct | class | |
|---|---|---|
| Typ | Wert (Kopie) | Referenz |
| Vererbung | nein | ja |
deinit | nein | ja |
| Standard in Swift | bevorzugen | wenn Identität/Vererbung nötig |
Swift verwaltet Klassen per ARC (automatische Referenzzählung): Es gibt keinen Garbage Collector; Zyklen vermeidet man mit weak/unowned.
Enums
Swift-Enums sind mächtig: Sie haben Methoden, Rohwerte und zugeordnete Werte.
enum Richtung: CaseIterable {
case nord, ost, sued, west
func gegenteil() -> Richtung {
switch self {
case .nord: return .sued
case .sued: return .nord
case .ost: return .west
case .west: return .ost
}
}
}
enum Planet: Int { case merkur = 1, venus, erde } // Rohwerte
enum Ergebnis {
case erfolg(wert: Int)
case fehler(grund: String)
case laden
}
func zeige(_ e: Ergebnis) -> String {
switch e {
case .erfolg(let w): return "Wert \(w)"
case .fehler(let g): return "Fehler: \(g)"
case .laden: return "lädt ..."
}
}
print(Richtung.nord.gegenteil(), Richtung.allCases.count, Planet.erde.rawValue, Planet(rawValue: 2) as Any)
print(zeige(.erfolg(wert: 42)), zeige(.fehler(grund: "kaputt")), zeige(.laden))
enum Optionaler<T> { case nichts, etwas(T) } // Generischer Enum (so ist Optional gebaut)
print(Optionaler.etwas(5))Ausgabe:
sued 4 3 Optional(prog.Planet.venus)
Wert 42 Fehler: kaputt lädt ...
etwas(5)Merke
struct= Werttyp, bevorzugt;mutatingfür ändernde Methodenclass= Referenztyp mit Vererbung,init,deinit, ARCenummit Methoden, Rohwerten und zugeordneten Werten;switchist vollständig- Berechnete Eigenschaften,
static,private(set) ===vergleicht Identität von Objekten
Übungsaufgabe
Modelliere Formen (Kreis, Rechteck) als Enum mit zugeordneten Werten und berechne die Fläche.
Quiz zur Selbstkontrolle
Was passiert bei var b = a, wenn a ein struct ist?
- b ist eine unabhängige Kopie (richtig)
- b zeigt auf dasselbe Objekt
- Ein Fehler
- a wird gelöscht
Was bedeutet mutating?
- Die Methode darf self (die Struct-Eigenschaften) ändern (richtig)
- Die Methode ist veraltet
- Die Methode ist privat
- Die Methode ist asynchron
Wie verwaltet Swift den Speicher von Klassen?
- Mit automatischer Referenzzählung (ARC) (richtig)
- Mit Garbage Collector
- Manuell mit free
- Gar nicht
Weiter im Kurs
Zurück: Funktionen, Closures und Collections
Weiter: Protokolle, Generics, Extensions und Fehler
Alle Kapitel: Swift im Überblick