تبديل النوع (Type Switch)
جزء من قسم Logic & Flow في رحلة GO على Coddy — الدرس 18 من 68.
بينما تعمل تأكيدات النوع (type assertions) بشكل جيد للتحقق من نوع واحد، فغالبًا ما تحتاج إلى التعامل مع أنواع محتملة متعددة لمتغير واجهة (interface variable). وهنا تبرز الفائدة الكبيرة لتبديل النوع (type switch) - فهو يوفر طريقة نظيفة لتنفيذ إجراءات مختلفة بناءً على النوع الفعلي (concrete type).
يستخدم تبديل النوع (type switch) هذا النحو الخاص: switch v := i.(type). لاحظ الكلمة المفتاحية (type) بدلاً من نوع محدد. المتغير v سيحتوي على القيمة الفعلية بنوعها الملموس في كل حالة:
func describe(data interface{}) {
switch v := data.(type) {
case int:
fmt.Printf("Integer: %d\n", v)
case string:
fmt.Printf("String: %s\n", v)
case bool:
fmt.Printf("Boolean: %t\n", v)
default:
fmt.Printf("Unknown type: %T\n", v)
}
}في كل حالة، يمتلك v تلقائياً النوع الصحيح - لا حاجة لتأكيد نوع (type assertion) إضافي. وهذا يجعل تبديلات الأنواع (type switches) أكثر تنظيماً بكثير من ربط عدة تأكيدات للأنواع بعبارات if-else، خاصة عندما تحتاج إلى التعامل مع عدة أنواع مختلفة في مكان واحد.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
التحدي
سهلفي هذا التحدي، ستتدرب على استخدام مفاتيح النوع (type switches) للتعامل مع أنواع بيانات متعددة في نظام إشعارات. ستقوم بإنشاء وظيفة تعالج أنواعاً مختلفة من الإشعارات وتنسقها بشكل مناسب بناءً على نوعها الملموس.
ستتلقى مدخلين:
- سلسلة نصية تمثل نوع الإشعار (على سبيل المثال،
"email"، أو"sms"، أو"push"، أو"alert") - سلسلة نصية تمثل محتوى الإشعار أو قيمته
مهمتك هي:
- إنشاء وظيفة تسمى
processNotificationتأخذ معامل من نوعinterface{} - بناءً على مدخل نوع الإشعار، قم بتحويل المحتوى إلى نوع Go المناسب وتخزينه في متغير من نوع
interface{}:- بالنسبة لـ
"email": استخدم المحتوى كسلسلة نصية (string) - بالنسبة لـ
"sms": قم بتحويل المحتوى إلى عدد صحيح (integer) (يمثل عدد الأحرف) - بالنسبة لـ
"push": قم بتحويل المحتوى إلى قيمة منطقية (boolean) (true لـ "enabled"، و false لأي شيء آخر) - بالنسبة لـ
"alert": قم بتحويل المحتوى إلى float64 (يمثل مستوى الأولوية)
- بالنسبة لـ
- استدعاء وظيفة
processNotificationبالقيمة المحولة - داخل
processNotification، استخدم مفتاح النوع (type switch) للتعامل مع كل نوع وطباعة الرسالة المناسبة:- بالنسبة لـ
string:"Email notification: [value]" - بالنسبة لـ
int:"SMS notification with [value] characters" - بالنسبة لـ
bool:"Push notifications: [value]" - بالنسبة لـ
float64:"Alert with priority: [value]" - لأي نوع آخر:
"Unknown notification type"
- بالنسبة لـ
استخدم حزمة strconv لتحويل السلاسل النصية. بالنسبة لتحويل القيمة المنطقية، يجب أن تؤدي القيمة "enabled" فقط إلى true. يوضح هذا التحدي كيف توفر مفاتيح النوع (type switches) طريقة نظيفة للتعامل مع أنواع متعددة في هيكل تحكم واحد، مما يمنحك تلقائياً القيمة المكتوبة بشكل صحيح في كل حالة.
ورقة مرجعية
يوفر تبديل النوع (type switch) طريقة نظيفة للتعامل مع أنواع متعددة محتملة لمتغير واجهة (interface variable) باستخدام الصيغة switch v := i.(type):
func describe(data interface{}) {
switch v := data.(type) {
case int:
fmt.Printf("Integer: %d\n", v)
case string:
fmt.Printf("String: %s\n", v)
case bool:
fmt.Printf("Boolean: %t\n", v)
default:
fmt.Printf("Unknown type: %T\n", v)
}
}في كل حالة، يمتلك المتغير v تلقائياً النوع الملموس (concrete type) الصحيح، مما يلغي الحاجة إلى تأكيدات إضافية للنوع (type assertions).
جرّب بنفسك
package main
import (
"fmt"
"strconv"
)
func main() {
// قراءة المدخلات
var notificationType string
var content string
fmt.Scanln(¬ificationType)
fmt.Scanln(&content)
// TODO: اكتب الكود الخاص بك أدناه
// 1. قم بإنشاء دالة processNotification التي تأخذ معامل من نوع interface{}
// 2. قم بتحويل المحتوى (content) إلى النوع المناسب بناءً على نوع الإشعار (notificationType)
// 3. قم باستدعاء processNotification بالقيمة المحولة
// 4. استخدم type switch داخل processNotification للتعامل مع الأنواع المختلفة
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس 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)ملخص - الأشكال والسلوكيات