0Pricing
Go Academy · درس

استدعاءات الدوال الديناميكية

استدعاء الدوال وضبط القيم عبر reflect

استدعاءات الدوال الديناميكية درس مجاني في Go Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Go Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Go Academy 4 دروس في المجموع.

reflect.Value.Call

تستدعي Value.Call(args) الدالة التي تمثلها Value باستخدام الوسائط المعطاة (بصفتها []reflect.Value)، وتعيد النتائج بصفتها []reflect.Value.

fn := reflect.ValueOf(add)
results := fn.Call([]reflect.Value{
    reflect.ValueOf(2),
    reflect.ValueOf(3),
})
fmt.Println(results[0].Int()) // 5

التحقق من أنواع الوسائط

تأكّد من تطابق أنواع الوسائط مع توقيع الدالة قبل الاستدعاء. تتسبب الأنواع غير المتطابقة في حدوث panic.

t := reflect.TypeOf(fn)
if t.NumIn() != len(args) { panic("wrong arg count") }
for i, arg := range args {
    if !reflect.TypeOf(arg).AssignableTo(t.In(i)) { panic("type mismatch") }
}

الدوال متغيرة الوسائط

استدعِ دالة متغيرة الوسائط باستخدام Value.Call (مع بسط الشريحة) أو Value.CallSlice (مع تمرير وسائط الدالة متغيرة الوسائط كقيمة شريحة):

sum := reflect.ValueOf(func(ns ...int) int {
    total := 0
    for _, n := range ns { total += n }
    return total
})
args := reflect.ValueOf([]int{1,2,3})
results := sum.CallSlice([]reflect.Value{args})

reflect.MakeFunc

تنشئ reflect.MakeFunc دالة جديدة أثناء وقت التشغيل باستخدام نوع معيّن وجسم تغليفي. وتُستخدم لإنشاء دوال محوِّلة للواجهات.

t := reflect.TypeOf(func(int) string { return "" })
fn := reflect.MakeFunc(t, func(args []reflect.Value) []reflect.Value {
    return []reflect.Value{reflect.ValueOf(strconv.Itoa(args[0].Interface().(int)))}
})

استدعاء الطرق بالاسم

استرجع طريقةً بالاسم واستدعها:

v := reflect.ValueOf(myObj)
m := v.MethodByName("Process")
if m.IsValid() {
    m.Call(nil)
}

التحقق من وجود طريقة

تحقّق دائمًا من m.IsValid() قبل الاستدعاء؛ إذ تعيد MethodByName قيمة Value صفرية إذا لم تُعثر على الطريقة، ويؤدي استدعاء القيمة الصفرية إلى panic.

حالات استخدام الاستدعاء الديناميكي

تُستخدم استدعاءات الدوال الديناميكية في أنظمة الإضافات (استدعاء الدوال باستخدام أسماء نصية)، وأطر الاختبار (استدعاء دوال TestXxx)، وموزّعات RPC (ربط أسماء الطرق بالمعالجات)، والمزيّنات.

الأداء

يكون reflect.Call أبطأ من الاستدعاء المباشر بنحو 10 إلى 50 مرة. خزّن قيمة reflect.Value للدوال كثيرة الاستدعاء مؤقتًا، وتجنّب استخدامها في الحلقات الساخنة.

غلاف آمن للأنواع

غلّف الاستدعاءات الديناميكية في مساعد مكتوب الأنواع ينفّذ آليات reflect مرة واحدة أثناء بدء التشغيل، ثم يستدعي Value المخزنة مؤقتًا بشكل متكرر:

type Processor func(context.Context, []byte) ([]byte, error)
// Build at startup, reuse at request time

معالجة القيمة المُعادة للخطأ

إذا أعادت الدالة خطأً بوصفه النتيجة الأخيرة، فاستخرجه وتحقّق منه:

results := fn.Call(args)
if !results[len(results)-1].IsNil() {
    return results[len(results)-1].Interface().(error)
}

بدائل الانعكاس

إذا كانت مجموعة الدوال معروفة أثناء التصريف، فاستخدم خريطة لقيم الدوال (map[string]func(...)) بدلًا من الانعكاس؛ فهي أكثر أمانًا وأسرع.

handlers := map[string]func(ctx context.Context, req []byte) []byte{
    "greet": greetHandler,
}

تحقق سريع

ماذا تعيد reflect.Value.Call؟

مراجعة: استدعاءات الدوال الديناميكية

النقاط الرئيسية:

  • يستدعي Value.Call([]reflect.Value) الدالة ويعيد []reflect.Value
  • تحقّق من m.IsValid() قبل استدعاء نتيجة MethodByName
  • تنشئ MakeFunc دالة جديدة بنوع معيّن أثناء وقت التشغيل
  • فضّل map[string]func على الانعكاس عندما تكون مجموعة الدوال معروفة

الأسئلة الشائعة

هل درس «استدعاءات الدوال الديناميكية» مجاني؟

نعم — نص درس «استدعاءات الدوال الديناميكية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Go Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Go Academy 4 دروس في المجموع.

ماذا ستتعلم في «استدعاءات الدوال الديناميكية»؟

استدعاء الدوال وضبط القيم عبر reflect تتمرن على Go Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Go Academy؟

لا تُشترط خبرة سابقة. Go Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «استدعاءات الدوال الديناميكية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Go Academy هذا؟

نعم. كل درس في Go Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. ‏reflect.Type وreflect.Value
  2. فحص حقول البُنى ووسومها
  3. استدعاءات الدوال الديناميكية
  4. الانعكاس عمليًا: المُسلسِلات
← العودة إلى Go Academy