Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

للقراءة فقط من الخارج

جزء من قسم البرمجة كائنية التوجه في رحلة 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
challenge icon

التحدي

سهل

أكمل الصنف 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)")
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: Playground لـ Swift