Funzioni generiche
Fa parte della sezione Programmazione orientata agli oggetti del percorso Swift di Coddy. Lezione 34 di 57.
Una funzione generica funziona con qualsiasi tipo. Il segnaposto tra parentesi angolari, spesso T, indica il tipo utilizzato da chi chiama la funzione, e Swift lo deduce a ogni chiamata:
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"]))Output:
[3, 1]
["a", "c"]All'interno della funzione non si sa nulla su T, quindi sono consentite solo le operazioni valide per ogni tipo. Un vincolo come T: Comparable ne consente altre, in questo caso l'operatore <:
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"])!)Output:
9
zucchiniI generics mantengono il tipo esatto, a differenza di Any. Il risultato di largest su [Int] è un Int?, quindi può essere usato nelle operazioni aritmetiche senza eseguire un cast:
func largest<T: Comparable>(_ items: [T]) -> T? {
items.max()
}
let top = largest([3, 7, 5]) ?? 0
print(top * 10)Output:
70Una funzione può avere diversi segnaposto e i vincoli possono specificare protocolli definiti da te:
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"))Output:
7
10
1 & oneSfida
FacileScrivi la funzione generica countWhere(_:_:) che accetta un array di qualsiasi tipo e un predicato (T) -> Bool e restituisce quanti elementi lo soddisfano, e mostCommon(_:) che accetta un array di qualsiasi tipo Hashable e restituisce il suo elemento più frequente (quello che compare per primo nell’array in caso di parità nei conteggi), oppure nil se l’array è vuoto.
Il codice fornito legge una riga di parole separate da virgole e una riga di numeri. Stampa il numero di parole più lunghe di 3 caratteri, la parola più frequente, il numero di numeri pari e il numero più frequente.
Il tuo codice va inserito in Functions.swift. main.swift contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
// Supplied input/output code: keep it as it is
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")
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiMetodi e selfInizializzatoriLe classi sono riferimentiRiepilogo - Tessera della biblioteca4Incapsulamento
Controllo degli accessiSola lettura dall’esternoProteggere lo statoInizializzatori che possono fallireRiepilogo - Conto bancario7Polimorfismo e tipi generici
PolimorfismoCasting dei tipiFunzioni genericheTipi genericiRipasso - Calcolatore di forme2Struct e tipi valore
Le structSemantica dei valoriMetodi mutantiStruct o classeRiepilogo - Articolo di inventario5Ereditarietà
SottoclassiSovrascrivere i metodiInizializzatori e superfinal e gerarchieRiepilogo - Gerarchia dei dipendenti8Protocolli standard
CustomStringConvertibleEquatableComparableHashableRiepilogo - Ordinamento personalizzato11Progetto: Gestione della biblioteca
Libri e utentiPrestito dei libriEsercitati da solo: Playground Swift