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

الـ Pointer Receivers مقابل الـ Value Receivers

جزء من قسم Object Oriented Programming في رحلة GO على Coddy — الدرس 8 من 107.

يمكن أن تمتلك الدوال (Methods) إما مستقبل قيمة (value receiver) أو مستقبل مؤشر (pointer receiver). يعمل مستقبل القيمة على نسخة من الهيكل (struct). بينما يعمل مستقبل المؤشر على الهيكل الأصلي ويمكنه تعديل حقوله.

مستقبل القيمة (Value receiver) — يعمل على نسخة

type Counter struct {
    Count int
}

func (c Counter) GetCount() int {
    return c.Count
}

// هذا لا يقوم بتعديل الأصل
func (c Counter) IncrementWrong() {
    c.Count++ // يغير النسخة فقط!
}

مستقبل المؤشر — يقوم بتعديل الأصل

// هذا يقوم بتعديل الأصل بالفعل
func (c *Counter) Increment() {
    c.Count++
}

func (c *Counter) Reset() {
    c.Count = 0
}

استخدام كليهما معاً

func main() {
    counter := Counter{Count: 0}

    counter.Increment()
    counter.Increment()
    fmt.Println(counter.GetCount()) // المخرجات: 2

    counter.Reset()
    fmt.Println(counter.GetCount()) // المخرجات: 0
}

استخدم مستقبل قيمة (value receiver) عندما تقوم الدالة (method) بقراءة البيانات فقط. استخدم مستقبل مؤشر (pointer receiver) (*StructName) عندما تحتاج الدالة إلى تعديل حقول الـ struct. تتعامل لغة Go تلقائيًا مع عملية الإسناد (referencing) — حيث يمكنك استدعاء كليهما بنفس الطريقة.

challenge icon

التحدي

متوسط

أضف دوال (methods) إلى هيكل Wallet باستخدام أنواع المستقبلات (receiver types) الصحيحة:

  • GetBalance — مستقبل قيمة (value receiver)، يعيد الرصيد الحالي
  • Deposit — مستقبل مؤشر (pointer receiver)، يضيف المبلغ إلى الرصيد
  • Withdraw — مستقبل مؤشر (pointer receiver)، يطرح المبلغ فقط في حال توفر أموال كافية

ورقة مرجعية

يمكن أن تحتوي الطرق (Methods) إما على مستقبل قيمة (value receiver) أو مستقبل مؤشر (pointer receiver). يعمل مستقبل القيمة على نسخة من الهيكل (struct). بينما يعمل مستقبل المؤشر على الهيكل الأصلي ويمكنه تعديل حقوله.

مستقبل القيمة (Value receiver) — يعمل على نسخة:

type Counter struct {
    Count int
}

func (c Counter) GetCount() int {
    return c.Count
}

مستقبل المؤشر (Pointer receiver) — يعدل الأصل:

func (c *Counter) Increment() {
    c.Count++
}

استخدم مستقبل القيمة (value receiver) عندما تقوم الطريقة بقراءة البيانات فقط. استخدم مستقبل المؤشر (pointer receiver) (*StructName) عندما تحتاج الطريقة إلى تعديل حقول الهيكل.

جرّب بنفسك

package main

import "fmt"

func main() {
    var balance, deposit, withdraw float64
    fmt.Scan(&balance, &deposit, &withdraw)

    w := Wallet{Balance: balance}

    fmt.Printf("Balance: %.2f\n", w.GetBalance())

    w.Deposit(deposit)
    fmt.Printf("After deposit: %.2f\n", w.GetBalance())

    w.Withdraw(withdraw)
    fmt.Printf("After withdrawal: %.2f\n", w.GetBalance())

    fmt.Printf("Final balance: %.2f\n", w.GetBalance())
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming