الانتقال إلى المحتوى الرئيسي
الوحدة 5 · الدرس 2 من 522/50 في الدورة~14 min
دروس الوحدة (2/5)

الطرق: القيمة مقابل مستقبل المؤشر

الطريقة في Go هي وظيفة ذات مستقبل: خاص المعلمة المعلنة بين func واسم الطريقة التي تربط طريقة إلى نوع. لا توجد فئات: يمكن تعريف الأساليب على أي نوع مسمى تم الإعلان عنه في الحزمة الحالية.

بناء الجملة

Go
type Person struct {
    Name string
}

func (p Person) Greet() string {
    return "ciao " + p.Name
}

p := Person{Name: "Ada"}
fmt.Println(p.Greet())   // "ciao Ada"

جهاز الاستقبال p Person يجعل Greet طريقة Person. داخل الطريقة، p هي متغير مثل أي متغير آخر.

مستقبل القيمة مقابل مستقبل المؤشر

Go
// VALUE receiver: operates on a COPY of the value
func (p Person) NameUpper() string {
    return strings.ToUpper(p.Name)
}

// POINTER receiver: operates on the original value, can mutate it
func (p *Person) Rename(n string) {
    p.Name = n
}

باستخدام جهاز استقبال المؤشر يمكنك تعديل جهاز الاستقبال والتغييرات مرئية خارج الطريقة. مع متلقي القيمة لا يمكنك فعل ذلك تعديل النسخة المحلية فقط.

Go
p := Person{Name: "Ada"}
p.Rename("Grace")
fmt.Println(p.Name)   // "Grace" — change is visible

متى تستخدم جهاز استقبال المؤشر

القواعد العملية حسب الأولوية:

  1. يجب عليك تعديل جهاز الاستقبال → جهاز استقبال المؤشر. إلزامي.
  2. البنية كبيرة (عشرات الحقول والمصفوفات بالداخل) → المؤشر المتلقي لتجنب النسخ باهظة الثمن.
  3. الاتساق: إذا كانت هناك طريقة واحدة على الأقل من النوع تحتوي على جهاز استقبال مؤشر، فاستخدم جهاز استقبال المؤشر للآخرين أيضا. اتفاقية مهمة جداً ل واجهات (الوحدة 6).
  4. أنواع "القيمة" الصغيرة وغير القابلة للتغيير (الوقت.الوقت، الأعداد المركبة، الصغيرة البنيات) → مستقبل القيمة، أكثر قابلية للقراءة.

طرق على الأنواع غير الهيكلية

يمكنك تعريف التوابع على أي نوع NAMED معلن في الحزمة الخاصة بك:

Go
type Celsius float64

func (c Celsius) ToFahrenheit() float64 {
    return float64(c)*9/5 + 32
}

t := Celsius(20)
fmt.Println(t.ToFahrenheit())  // 68

لا يمكنك تحديدها على أنواع من الحزم الأخرى (على سبيل المثال int، string): يجب عليك قم أولاً بإنشاء نوع محلي مسمى.

جربه

تمرين#go.m5.l2.e1
المحاولات: 0جارٍ التحميل…

أضف أسلوب سلسلة Greet() (مستقبل القيمة) إلى الشخص الذي يُرجع "ciao <Name>".

جارٍ تحميل المحرر…
إظهار التلميح

المتلقي بين قوسين قبل اسم الطريقة.

الحل متاح بعد 3 من المحاولات

تمرين#go.m5.l2.e2
المحاولات: 0جارٍ التحميل…

أضف طريقة إعادة تسمية (سلسلة n) باستخدام جهاز استقبال POINTER الذي يغير p.Name.

جارٍ تحميل المحرر…
إظهار التلميح

مستقبل المؤشر: `(ع * شخص)`.

الحل متاح بعد 3 من المحاولات

Quiz#go.m5.l2.e3
جاهز

متى يجب عليك استخدام جهاز استقبال المؤشر (p*T)؟

Go
func (t ?T) M() { ... }
خيارات الإجابة

خلاصة

  • الطريقة = الوظيفة مع جهاز الاستقبال: func (r T) Name(...) ... { ... }.
  • مستقبل القيمة: يعمل على نسخة؛ مستقبل المؤشر: يعمل على الأصل.
  • يقوم Go بإجراء التحويل T ↔ *T تلقائيًا في موقع الاتصال.
  • مستقبل المؤشر عند: الطفرة + البنية الكبيرة + التناسق مع الطرق الأخرى من النوع.
  • لا تخلط مطلقًا بين مستقبلات القيمة والمؤشر من نفس النوع.
  • يتم تنفيذ الطرق على أنواع NAMED في الحزمة الحالية (بما في ذلك غير البنية).