الـ Pointer Receivers
جزء من قسم Logic & Flow في رحلة GO على Coddy — الدرس 8 من 68.
بينما تعمل مستقبلات القيمة (value receivers) مع نسخ من الـ structs، تعمل مستقبلات المؤشر (pointer receivers) مباشرة مع مثيل الـ struct الأصلي. عندما تقوم بتعريف method بمستقبل مؤشر، يمكن للـ method تعديل البيانات الأصلية لأنها تستقبل مؤشراً إلى الـ struct بدلاً من نسخة.
لإنشاء مستقبل مؤشر (pointer receiver)، يمكنك إضافة علامة النجمة * قبل اسم النوع في إعلان المستقبل:
type Person struct {
Name string
Age int
}
func (p *Person) haveBirthday() {
p.Age++ // هذا يعدل الهيكل (struct) الأصلي
}في هذا المثال، (p *Person) هو مستقبل مؤشر (pointer receiver). عندما تستدعي التابع haveBirthday على نسخة (instance) من Person، يستقبل التابع مؤشراً إلى الهيكل (struct) الأصلي. أي تغييرات يتم إجراؤها على حقول الهيكل من خلال هذا المؤشر ستؤدي إلى تعديل البيانات الأصلية بشكل دائم.
تعد مستقبلات المؤشرات (Pointer receivers) ضرورية عندما تحتاج دوالك (methods) إلى تحديث حقول الـ struct، مما يجعلها مثالية للعمليات التي تغير حالة بياناتك.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
التحدي
سهلفي هذا التحدي، ستتدرب على إنشاء دوال (methods) بمستقبلات مؤشر (pointer receivers) من خلال بناء نظام حساب بنكي بسيط. ستقوم بإنشاء هيكل Account وتعريف دوال يمكنها تعديل رصيد الحساب باستخدام مستقبلات المؤشر.
ستتلقى ثلاثة مدخلات:
- سلسلة نصية تمثل اسم صاحب الحساب (مثلاً،
"John Smith") - سلسلة نصية تمثل رصيد الحساب الأولي (مثلاً،
"1000.50") - سلسلة نصية تمثل مبلغ المعاملة (مثلاً،
"250.75")
مهمتك هي:
- تعريف هيكل
Accountبحقلين:Name(string) وBalance(float64) - إنشاء دالة تسمى
depositبمستقبل مؤشر (pointer receiver) تضيف المبلغ المعطى إلى رصيد الحساب - إنشاء دالة تسمى
withdrawبمستقبل مؤشر (pointer receiver) تطرح المبلغ المعطى من رصيد الحساب - إنشاء دالة تسمى
displayBalanceبمستقبل قيمة (value receiver) تطبع معلومات الحساب بالتنسيق التالي:"Account: [name], Balance: $[balance]" - تحليل المدخلات لإنشاء مثيل (instance) من
Account - استدعاء
displayBalanceلإظهار الرصيد الأولي - استدعاء
depositبمبلغ المعاملة - استدعاء
displayBalanceلإظهار الرصيد بعد الإيداع - استدعاء
withdrawبمبلغ المعاملة - استدعاء
displayBalanceلإظهار الرصيد النهائي
يجب عرض الرصيد بدقة منزلتين عشريتين. يوضح هذا التحدي كيف تسمح مستقبلات المؤشر للدوال بتعديل بيانات الهيكل الأصلية، على عكس مستقبلات القيمة التي تعمل مع النسخ.
ورقة مرجعية
تعمل مستقبلات المؤشرات (Pointer receivers) مباشرة مع نسخة الـ struct الأصلية من خلال استقبال مؤشر للـ struct بدلاً من نسخة منه. يتيح ذلك للدوال (methods) تعديل البيانات الأصلية.
لإنشاء مستقبل مؤشر، أضف علامة النجمة * قبل اسم النوع في إعلان المستقبل:
type Person struct {
Name string
Age int
}
func (p *Person) haveBirthday() {
p.Age++ // هذا يعدل الـ struct الأصلي
}استخدم مستقبلات المؤشرات عندما تحتاج الدوال الخاصة بك إلى تحديث حقول الـ struct، مما يجعلها مثالية للعمليات التي تغير حالة بياناتك.
جرّب بنفسك
package main
import (
"fmt"
"strconv"
)
// TODO: قم بتعريف هيكل الحساب (Account struct) هنا
// TODO: قم بتعريف طريقة الإيداع (deposit method) مع مستقبل مؤشر (pointer receiver) هنا
// TODO: قم بتعريف طريقة السحب (withdraw method) مع مستقبل مؤشر (pointer receiver) هنا
// TODO: قم بتعريف طريقة عرض الرصيد (displayBalance method) مع مستقبل قيمة (value receiver) هنا
func main() {
// قراءة المدخلات
var name string
var initialBalanceStr string
var transactionAmountStr string
fmt.Scanln(&name)
fmt.Scanln(&initialBalanceStr)
fmt.Scanln(&transactionAmountStr)
// تحويل المدخلات النصية إلى الأنواع المناسبة
initialBalance, _ := strconv.ParseFloat(initialBalanceStr, 64)
transactionAmount, _ := strconv.ParseFloat(transactionAmountStr, 64)
// TODO: قم بإنشاء مثيل للحساب (Account instance)
// TODO: عرض الرصيد الأولي، إجراء الإيداع، عرض الرصيد، إجراء السحب، عرض الرصيد النهائي
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1تدفق التحكم المتقدم
جملة Switch مع `fallthrough`الخروج من الحلقات المتداخلةالاستمرار في حلقة محددةجملة `goto`ملخص - التحكم المتقدم في الحلقات2الـ Structs والميثودز (Methods)
تعريف الـ Methods على الـ Structsالـ Value Receiversالـ Pointer Receiversاختيار الـ Receiversالـ Methods مقابل الـ Functionsملخص - سلوك الـ Struct5تعمق في الـ Maps
Maps من نوع Structsالـ Pointers كقيم في الـ Mapsالتحقق من الـ Nil Mapsمقارنة الـ Mapsمراجعة - عداد تكرار الكلمات3الواجهات (الأساسيات)
ما هي الواجهة؟تعريف الواجهةتطبيق الواجهةاستخدام أنواع الواجهاتالواجهة الفارغةتأكيدات النوع (Type Assertions)تبديل النوع (Type Switch)ملخص - الأشكال والسلوكيات