Menu
Coddy logo textTech

CustomStringConvertible

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Swift של Coddy. שיעור 37 מתוך 57.

כשמדפיסים ערך, Swift מציגה כברירת מחדל את הטיפוס ואת המאפיינים שלו, ובמקרה של מחלקה — רק את שם הטיפוס. אימוץ הפרוטוקול CustomStringConvertible והגדרת description מאפשרים לשלוט בטקסט:

struct Money {
    let cents: Int
}
struct Price: CustomStringConvertible {
    let cents: Int
    var description: String { "$\(cents / 100).\(cents % 100)" }
}

print(Money(cents: 1250))
print(Price(cents: 1250))

פלט:

Money(cents: 1250)
$12.50

השדה description משמש את print, את שיבוץ המחרוזות ואת String(describing:), ולכן מאפיין אחד שולט בכל המקומות שבהם הערך מוצג:

struct Point: CustomStringConvertible {
    let x: Int, y: Int
    var description: String { "(\(x), \(y))" }
}

let p = Point(x: 2, y: 5)
print("start at \(p)")
print([p, Point(x: 0, y: 0)])
print(String(describing: p).count)

פלט:

start at (2, 5)
[(2, 5), (0, 0)]
6

מחלקות מפיקות מכך את התועלת הרבה ביותר, משום שהדפסת מופע של מחלקה מציגה אחרת רק את שם הטיפוס שלה:

class Account {
    let owner: String
    var balance: Int
    init(owner: String, balance: Int) { self.owner = owner; self.balance = balance }
}

class NamedAccount: CustomStringConvertible {
    let owner: String
    var balance: Int
    init(owner: String, balance: Int) { self.owner = owner; self.balance = balance }
    var description: String { "\(owner): \(balance)" }
}

print(Account(owner: "Ada", balance: 5))
print(NamedAccount(owner: "Ada", balance: 5))

פלט:

main.Account
Ada: 5

יש לשמור את description קצר וקריא לאנשים. הוא אינו מיועד לניתוח, ואינו אמור לשנות את הערך:

enum Status: CustomStringConvertible {
    case active, suspended
    var description: String {
        switch self {
        case .active: return "active"
        case .suspended: return "suspended"
        }
    }
}
challenge icon

אתגר

קל

גרום ל-struct Fraction (מונה, מכנה) להתאים ל-CustomStringConvertible. ה-description שלו מציג את השבר בצורתו המצומצמת ביותר: 6/8 מודפס כ-3/4, 4/2 כ-2, 0/5 כ-0, ובשבר שלילי הסימן נשאר לפניו (-1/2). כתוב פונקציית עזר gcd(_:_:) לצמצום.

הקוד שסופק קורא שברים מהצורה a/b, אחד בכל שורה, ומדפיס כל אחד מהם באמצעות print.

הקוד שלך ייכתב ב-Fraction.swift וב-Functions.swift. הקובץ main.swift מכיל את קוד הקלט/פלט שסופק, ואי אפשר לערוך אותו.

נסו בעצמכם

// קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
    let p = line.split(separator: "/").map { Int($0)! }
    print(Fraction(numerator: p[0], denominator: p[1]))
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: Swift אונליין