לקריאה בלבד מבחוץ
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Swift של Coddy. שיעור 18 מתוך 57.
לעיתים קרובות, קוד חיצוני צריך לקרוא מאפיין, אבל לא לשנות אותו. private(set) משאיר את ה-getter ברמת הגישה הרגילה והופך רק את ה-setter לפרטי:
struct Counter {
private(set) var count = 0
mutating func increment() {
count += 1
}
}
var c = Counter()
c.increment()
print(c.count)
// c.count = 99 // שגיאה: ה-setter פרטיפלט:
1זה מתאים לערכים שחייבים להשתנות רק לפי כלל, כמו ניקוד שיכול רק לעלות בעקבות פעולות תקינות:
class Player {
let name: String
private(set) var score = 0
private(set) var history: [Int] = []
init(name: String) { self.name = name }
func award(_ points: Int) {
guard points > 0 else { return }
score += points
history.append(points)
}
}
let p = Player(name: "Ada")
p.award(10)
p.award(-5)
p.award(3)
print(p.score)
print(p.history)פלט:
13
[10, 3]מאפיין let הוא לקריאה בלבד עבור כולם לאחר שהמופע נוצר, כולל המתודות של הטיפוס עצמו. private(set) var נשאר ניתן לשינוי בתוך הטיפוס. בחרו ב-let עבור ערכים שאינם משתנים לעולם לאחר יצירתם:
class Order {
let id: Int // לעולם לא משתנה
private(set) var status = "new" // משתנה, אבל רק בתוך Order
init(id: Int) { self.id = id }
func ship() { status = "shipped" }
}מאפיין מחושב לקריאה בלבד הוא דרך נוספת לחשוף מידע בלי לאפשר שינויים, משום שאין לו כלל מגדיר:
struct Cart {
private var prices: [Int] = []
var total: Int { prices.reduce(0, +) }
var count: Int { prices.count }
mutating func add(_ price: Int) { prices.append(price) }
}
var cart = Cart()
cart.add(4)
cart.add(6)
print("\(cart.count) items, total \(cart.total)")פלט:
2 items, total 10אתגר
קלהשלם את המחלקה Elevator. אפשר לקרוא את floor ואת trips מחוץ למחלקה, אך רק המחלקה יכולה לשנות אותם (private(set)). goTo(_:) מעבירה בין קומה 0 לבין topFloor: מעבר תקין לקומה אחרת מעדכן את floor, מוסיף 1 ל-trips ומחזיר true; מעבר לא תקין או מעבר לאותה קומה מחזיר false.
הקוד שסופק קורא את הקומה העליונה ולאחר מכן את קומות היעד. הוא מדפיס floor 3 אחרי מעבר או stay 3 כאשר המעבר נדחה, ולבסוף trips: עם מספר הנסיעות.
יש לכתוב את הקוד שלך ב-Elevator.swift. הקובץ main.swift מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
// קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
var input: [String] = []
while let line = readLine() { input.append(line) }
let lift = Elevator(topFloor: Int(input[0])!)
for line in input.dropFirst() {
let moved = lift.goTo(Int(line)!)
print("\(moved ? "floor" : "stay") \(lift.floor)")
}
print("trips: \(lift.trips)")
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
תרגלו בעצמכם: Swift אונליין