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

الأساليب المعدِّلة

جزء من قسم البرمجة كائنية التوجه في رحلة Swift على Coddy. الدرس 9 من 57.

يجب وضع علامة mutating على أسلوب البنية الذي يغيّر خاصية. من دون هذه الكلمة المفتاحية، لا يتم تجميع الأسلوب، لأن أساليب نوع القيمة تتعامل مع self على أنه ثابت:

struct Counter {
    var count = 0

    mutating func increment() {
        count += 1
    }
}

var c = Counter()
c.increment()
c.increment()
print(c.count)

الناتج:

2

لا يمكن استدعاء طريقة مُعدِّلة إلا على var. أما على ثابت let فلا يُجمَّع الاستدعاء، لأن القيمة بأكملها ثابتة:

var a = Counter()
a.increment()        // جيد

let b = Counter()
// b.increment()     // خطأ: b هو ثابت let

تظل الأساليب التي تقرأ الخصائص فقط غير مغيرة، وتعمل أيضًا مع الثوابت. يحافظ التصميم الجيد على التغييرات في عدد قليل من الأساليب المغيرة:

struct Stack {
    var items: [Int] = []

    mutating func push(_ x: Int) { items.append(x) }
    mutating func pop() -> Int? { items.popLast() }
    func peek() -> Int? { items.last }
}

var s = Stack()
s.push(3)
s.push(8)
print(s.pop() ?? -1)
print(s.peek() ?? -1)

الناتج:

8
3

يمكن لطريقة مُعدِّلة استبدال self بالكامل، وهذا مفيد لإعادة تعيين قيمة:

struct Score {
    var points = 0
    var bonus = 0

    mutating func reset() {
        self = Score()
    }
}

var s = Score(points: 10, bonus: 3)
s.reset()
print(s.points + s.bonus)

الناتج:

0
challenge icon

التحدي

سهل

أكمل البنية Wallet. الدالتان add(_:) وspend(_:) تغيّران الحالة: تطرح spend المبلغ فقط عندما يتبقى مال كافٍ، وتُرجع ما إذا كانت قد فعلت ذلك. الدالة report() لا تغيّر الحالة وتُرجع balance 40.

يقرأ الكود المزوَّد الأوامر +n و-n، ويطبّقها على محفظة واحدة من نوع var، ويطبع denied عند رفض عملية الإنفاق، ثم يطبع report() في النهاية.

ضع الكود الخاص بك في Wallet.swift. يحتوي main.swift على كود الإدخال/الإخراج المزوَّد، ولا يمكن تعديله.

جرّب بنفسك

// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
var input: [String] = []
while let line = readLine() { input.append(line) }
var wallet = Wallet()
for cmd in input {
    let amount = Int(cmd.dropFirst())!
    if cmd.hasPrefix("+") {
        wallet.add(amount)
    } else if !wallet.spend(amount) {
        print("denied")
    }
}
print(wallet.report())
quiz iconاختبر نفسك

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

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

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