הרחבות לפרוטוקולים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Swift של Coddy. שיעור 29 מתוך 57.
הרחבת פרוטוקול מספקת מימוש ברירת מחדל למתודות של פרוטוקול. כל טיפוס שתואם לפרוטוקול מקבל אותו בחינם, וטיפוס עדיין יכול לספק גרסה משלו:
protocol Greeter {
var name: String { get }
func greet() -> String
}
extension Greeter {
func greet() -> String { "Hello, \(name)!" }
}
struct English: Greeter { let name: String }
struct Pirate: Greeter {
let name: String
func greet() -> String { "Ahoy, \(name)!" }
}
print(English(name: "Ada").greet())
print(Pirate(name: "Ada").greet())פלט:
Hello, Ada!
Ahoy, Ada!תוספת יכולה גם להוסיף מתודות חדשות שנבנות רק מהדרישות. טיפוס תואם כותב את החלק הקטן הנדרש ומקבל את השאר:
protocol Scored {
var points: [Int] { get }
}
extension Scored {
var total: Int { points.reduce(0, +) }
var best: Int { points.max() ?? 0 }
func summary() -> String { "total \(total), best \(best)" }
}
struct Player: Scored {
let points: [Int]
}
print(Player(points: [3, 9, 4]).summary())פלט:
total 16, best 9כך אפשר לשתף התנהגות בין מבנים, מחלקות ומטיפוסים מסוג enum ללא הורשה. הספרייה הסטנדרטית פועלת באותו אופן: כל Collection מקבלות את isEmpty, את first ואת map מהרחבות של פרוטוקולים.
extension Collection {
// isEmpty, first, map, filter, ... כולם מוגדרים כאן פעם אחת בלבד
// וכל מערך, קבוצה, מילון ומחרוזת מקבלים אותם
}הרחבה מוגבלת מוסיפה מתודות רק לסוגים מסוימים שעומדים בתנאים, באמצעות where:
protocol Container {
associatedtype Item
var items: [Item] { get }
}
extension Container where Item == Int {
var sum: Int { items.reduce(0, +) }
}
struct Box: Container {
var items: [Int]
}
print(Box(items: [2, 5]).sum)פלט:
7אתגר
קלהצהר על פרוטוקול Priced שדורש var price: Int { get } (בסנטים) ו-var formatted: String { get }. בהרחבת פרוטוקול, הגדר ברירת מחדל עבור formatted שמחזירה $4.50, והוסף מתודה isAffordable(budget:) שמחזירה האם המחיר נכנס בתקציב. התאם את המבנים Coffee (מחיר 450) ו-Sandwich (עם price מאוחסן) לפרוטוקול. על Coffee להחליף את ברירת המחדל של formatted ב-coffee $4.50.
הקוד שסופק קורא תקציב ולאחר מכן שורות coffee או sandwich,650. הוא מדפיס את formatted ואת yes או no עבור כל פריט.
הקוד שלך ייכתב בקבצים Priced.swift, Coffee.swift ו-Sandwich.swift. הקובץ main.swift מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
// קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
var input: [String] = []
while let line = readLine() { input.append(line) }
let budget = Int(input[0])!
for line in input.dropFirst() {
let item: any Priced = line == "coffee" ? Coffee() : Sandwich(price: Int(line.split(separator: ",")[1])!)
print("\(item.formatted) \(item.isAffordable(budget: budget) ? "yes" : "no")")
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
7פולימורפיזם וטיפוסים גנריים
פולימורפיזםהמרת טיפוסיםפונקציות גנריותטיפוסים גנרייםסיכום - מחשבון צורות6פרוטוקולים
הגדרת פרוטוקוליםטיפוסים התואמים לפרוטוקולהרחבות לפרוטוקוליםפרוטוקולים כטיפוסיםסיכום – מערכת תשלומיםתרגלו בעצמכם: Swift אונליין