الواجهة الفارغة
جزء من قسم Logic & Flow في رحلة GO على Coddy — الدرس 16 من 68.
حتى الآن، كنت تعمل مع الواجهات التي تتطلب دوالاً محددة، ولكن لدى Go واجهة خاصة مرنة للغاية: الواجهة الفارغة، التي تُكتب على النحو interface{}.
لا تمتلك الواجهة الفارغة (empty interface) أي متطلبات للدوال على الإطلاق، مما يعني أن أي نوع في لغة Go يحققها تلقائياً. وبما أن كل نوع ينفذ صفر من الدوال (كحد أدنى)، فإنه يمكن تعيين أي نوع لمتغير من نوع interface{}:
var anything interface{}
anything = 42 // int
anything = "hello" // string
anything = true // bool
anything = []int{1, 2, 3} // sliceهذا يجعل interface{} مفيداً للغاية عندما تحتاج إلى العمل مع بيانات من أنواع غير معروفة أو متغيرة. قد تواجه هذا عند قراءة ملفات التكوين، أو التعامل مع مدخلات المستخدم، أو العمل مع واجهات برمجة التطبيقات (APIs) التي تُرجع أنواع بيانات مختلفة بناءً على الموقف.
ومع ذلك، بما أن الواجهة الفارغة (empty interface) يمكنها استيعاب أي نوع، فستحتاج غالباً إلى تحديد النوع المخزن بداخلها بالفعل قبل أن تتمكن من استخدام القيمة بشكل مفيد. وهنا تصبح تأكيدات النوع (type assertions) ومفاتيح النوع (type switches) (والتي ستتعلم عنها لاحقاً) أدوات أساسية للعمل بأمان مع قيم interface{}.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
التحدي
سهلفي هذا التحدي، ستتدرب على العمل مع الواجهة الفارغة (empty interface) من خلال إنشاء معالج بيانات يمكنه التعامل مع أنواع مختلفة من القيم. ستقوم بإنشاء دالة تقبل معاملًا من نوع interface{} وتعالج أنواع بيانات متنوعة.
ستتلقى مدخلين:
- سلسلة نصية تمثل نوع البيانات (على سبيل المثال،
"int"، أو"string"، أو"bool"، أو"slice") - سلسلة نصية تمثل القيمة الفعلية (على سبيل المثال،
"42"، أو"hello"، أو"true"، أو"1,2,3")
مهمتك هي:
- إنشاء دالة تسمى
processDataتأخذ معاملًا من نوعinterface{}وتطبع معلومات حول القيمة - بناءً على نوع البيانات المدخل، قم بتحويل سلسلة القيمة النصية إلى نوع Go المناسب:
- بالنسبة لـ
"int": قم بالتحويل إلى عدد صحيح (integer) - بالنسبة لـ
"string": استخدمها كسلسلة نصية (string) - بالنسبة لـ
"bool": قم بالتحويل إلى قيمة منطقية (boolean) - بالنسبة لـ
"slice": قم بتحويل القيم المفصولة بفاصلة إلى شريحة من الأعداد الصحيحة (slice of integers)
- بالنسبة لـ
- استدعاء الدالة
processDataبالقيمة المحولة - داخل
processData، اطبع القيمة ونوعها بالتنسيق التالي:"Value: [value], Type: [type]"
بالنسبة لمدخل الشريحة (slice)، يجب تحويل السلسلة النصية المفصولة بفاصلة مثل "1,2,3" إلى []int{1, 2, 3}. يجب أن تعمل الدالة مع أي نوع لأنها تقبل interface{}، مما يوضح كيف يمكن للواجهة الفارغة أن تحمل قيمًا من أي نوع. استخدم fmt.Printf مع رموز التنسيق %v و %T لعرض القيمة والنوع على التوالي.
ورقة مرجعية
الواجهة الفارغة interface{} ليس لها متطلبات دوال (methods)، مما يعني أن أي نوع في لغة Go يحققها تلقائياً:
var anything interface{}
anything = 42 // int
anything = "hello" // string
anything = true // bool
anything = []int{1, 2, 3} // sliceتعتبر الواجهة الفارغة مفيدة للتعامل مع البيانات ذات الأنواع غير المعروفة أو المتغيرة، مثل ملفات الإعدادات، أو مدخلات المستخدم، أو واجهات برمجة التطبيقات (APIs) التي تعيد أنواع بيانات مختلفة.
استخدم fmt.Printf مع رموز التنسيق %v و %T لعرض قيمة ونوع متغير من نوع interface{}:
fmt.Printf("Value: %v, Type: %T", value, value)مساعدات تحويل مفيدة من المكتبة القياسية:
import (
"strconv"
"strings"
)
// Convert string to int
n, err := strconv.Atoi("42") // n = 42
// Convert string to bool
b, err := strconv.ParseBool("true") // b = true
// Split a string into a slice
parts := strings.Split("a,b,c", ",") // ["a", "b", "c"]جرّب بنفسك
package main
import (
"fmt"
)
func main() {
// قراءة المدخلات
var dataType string
var valueStr string
fmt.Scanln(&dataType)
fmt.Scanln(&valueStr)
// TODO: اكتب الكود الخاص بك أدناه
// 1. قم بإنشاء دالة processData التي تقبل interface{}
// 2. قم بتحويل valueStr إلى النوع المناسب بناءً على dataType
// 3. قم باستدعاء processData مع القيمة المحولة
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس 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)ملخص - الأشكال والسلوكيات