פונקציות גנריות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Swift של Coddy. שיעור 34 מתוך 57.
פונקציה גנרית פועלת עם כל סוג. מציין המיקום שבין סוגריים זוויתיים, לרוב T, מייצג את הסוג שבו משתמש הקורא, ו-Swift קובעת אותו בכל קריאה:
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"]))פלט:
[3, 1]
["a", "c"]בתוך הפונקציה לא ידוע דבר על T, ולכן מותרות רק פעולות שעובדות עבור כל סוג. אילוץ כגון T: Comparable מאפשר יותר; כאן, את האופרטור <:
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"])!)פלט:
9
zucchiniטיפוסים גנריים שומרים על הטיפוס המדויק, בניגוד ל־Any. התוצאה של largest על [Int] היא Int?, ולכן אפשר להשתמש בה בחישובים אריתמטיים בלי המרת טיפוס:
func largest<T: Comparable>(_ items: [T]) -> T? {
items.max()
}
let top = largest([3, 7, 5]) ?? 0
print(top * 10)פלט:
70לפונקציה יכולים להיות כמה מצייני מקום, ואילוצים יכולים לציין פרוטוקולים משלך:
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"))פלט:
7
10
1 & oneאתגר
קלכתבו את הפונקציה הגנרית countWhere(_:_:) שמקבלת מערך מכל טיפוס ומַנבא (T) -> Bool ומחזירה כמה איברים עומדים בתנאי, וכן את mostCommon(_:) שמקבלת מערך מטיפוס Hashable כלשהו ומחזירה את האיבר השכיח ביותר בו (האיבר שמופיע ראשון במערך כאשר יש שוויון במספר ההופעות), או nil עבור מערך ריק.
הקוד שסופק קורא שורה של מילים המופרדות בפסיקים ושורה של מספרים. הוא מדפיס את מספר המילים שאורכן יותר מ-3 תווים, את המילה השכיחה ביותר, את מספר המספרים הזוגיים ואת המספר השכיח ביותר.
הקוד שלכם צריך להיכתב בקובץ Functions.swift. הקובץ main.swift מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
// קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
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")
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
7פולימורפיזם וטיפוסים גנריים
פולימורפיזםהמרת טיפוסיםפונקציות גנריותטיפוסים גנרייםסיכום - מחשבון צורותתרגלו בעצמכם: Swift אונליין