Generische Funktionen
Teil des Abschnitts Objektorientierte Programmierung der Swift-Journey von Coddy. Lektion 34 von 57.
Eine generische Funktion funktioniert mit jedem Typ. Der Platzhalter in spitzen Klammern, häufig T, steht für den Typ, den der Aufrufer verwendet, und Swift trägt ihn bei jedem Aufruf ein:
func firstAndLast<T>(_ items: [T]) -> [T] {
guard let first = items.first, let last = items.last else { return [] }
return [first, last]
}
print(firstAndLast([3, 8, 1]))
print(firstAndLast(["a", "b", "c"]))Ausgabe:
[3, 1]
["a", "c"]Innerhalb der Funktion ist nichts über T bekannt, daher sind nur Operationen zulässig, die für jeden Typ funktionieren. Eine Einschränkung wie T: Comparable erlaubt mehr, hier den Operator <:
func largest<T: Comparable>(_ items: [T]) -> T? {
guard var best = items.first else { return nil }
for item in items where item > best { best = item }
return best
}
print(largest([4, 9, 2])!)
print(largest(["pear", "apple", "zucchini"])!)Ausgabe:
9
zucchiniGenerics behalten den exakten Typ bei, im Gegensatz zu Any. Das Ergebnis von largest auf [Int] ist ein Int?, daher kann es ohne Typumwandlung in arithmetischen Ausdrücken verwendet werden:
func largest<T: Comparable>(_ items: [T]) -> T? {
items.max()
}
let top = largest([3, 7, 5]) ?? 0
print(top * 10)Ausgabe:
70Eine Funktion kann mehrere Platzhalter haben, und Constraints können eigene Protokolle benennen:
protocol Scored { var score: Int { get } }
struct Player: Scored { let name: String; let score: Int }
struct Team: Scored { let score: Int }
func total<T: Scored>(_ items: [T]) -> Int {
items.reduce(0) { $0 + $1.score }
}
func pair<A, B>(_ a: A, _ b: B> -> String { "\(a) & \(b)" }
print(total([Player(name: "a", score: 3), Player(name: "b", score: 4)]))
print(total([Team(score: 10)]))
print(pair(1, "one"))Ausgabe:
7
10
1 & oneAufgabe
EinfachSchreibe die generische Funktion countWhere(_:_:), die ein Array eines beliebigen Typs und ein Prädikat (T) -> Bool entgegennimmt und zurückgibt, wie viele Elemente die Bedingung erfüllen, sowie mostCommon(_:), die ein Array eines beliebigen Hashable-Typs entgegennimmt und dessen häufigstes Element zurückgibt (bei gleicher Anzahl dasjenige, das im Array zuerst vorkommt) oder nil für ein leeres Array.
Der bereitgestellte Code liest eine durch Kommas getrennte Zeile mit Wörtern und eine Zeile mit Zahlen ein. Er gibt die Anzahl der Wörter mit mehr als 3 Zeichen, das häufigste Wort, die Anzahl der geraden Zahlen und die häufigste Zahl aus.
Dein Code gehört in Functions.swift. main.swift enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
// Gelieferter Ein-/Ausgabecode: belasse ihn wie er ist
var input: [String] = []
while let line = readLine() { input.append(line) }
let words = input[0].split(separator: ",").map(String.init)
let numbers = input[1].split(separator: ",").map { Int($0)! }
print(countWhere(words) { $0.count > 3 })
print(mostCommon(words) ?? "none")
print(countWhere(numbers) { $0 % 2 == 0 })
print(mostCommon(numbers).map { String($0) } ?? "none")
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Klassen und Objekte
Arbeiten mit DateienKlassen definierenMethoden und selfInitialisiererKlassen sind ReferenzenRückblick – Bibliotheksausweis4Kapselung
ZugriffskontrolleVon außen schreibgeschütztZustand schützenFehlschlagende InitialisiererRückblick – Bankkonto7Polymorphismus und Generika
PolymorphismusTypumwandlungGenerische FunktionenGenerische TypenZusammenfassung – Shape-Rechner2Strukturen und Werttypen
StrukturenWertsemantikVerändernde MethodenStruktur oder KlasseZusammenfassung – Inventarelement5Vererbung
UnterklassenMethoden überschreibenInitialisierer und superfinal und HierarchienRückblick – Mitarbeiterhierarchie8Standardprotokolle
CustomStringConvertibleEquatableComparableHashableRückblick – Benutzerdefiniertes Sortieren11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Swift-Playground