Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

ملخص - المجموعات العامة

جزء من قسم Object Oriented Programming في رحلة GO على Coddy — الدرس 72 من 107.

challenge icon

التحدي

سهل

لنقم ببناء هيكل بيانات Queue (طابور) عام يوضح كل ما تعلمته عن الـ generics في لغة Go! على عكس الـ stack (LIFO)، يتبع الـ queue ترتيب "الوارد أولاً يخرج أولاً" (FIFO) — أي أن العنصر الأول الذي تمت إضافته هو أول عنصر يتم إزالته.

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • queue.go: قم بتعريف مجموعة الـ queue العامة الخاصة بك.

    أنشئ هيكلاً عاماً (generic struct) باسم Queue[T any] يقوم بتخزين العناصر داخلياً. يجب أن يدعم الـ queue الخاص بك هذه العمليات:

    • Enqueue(item T) - يضيف عنصراً إلى نهاية الطابور.
    • Dequeue() (T, bool) - يزيل ويعيد العنصر من مقدمة الطابور، مع قيمة منطقية (boolean) تشير إلى النجاح (أعد القيمة الصفرية و false إذا كان الطابور فارغاً).
    • Peek() (T, bool) - يعيد العنصر الموجود في المقدمة دون إزالته (نفس نمط الإرجاع في Dequeue).
    • Size() int - يعيد عدد العناصر في الطابور.
    • IsEmpty() bool - يعيد true إذا كان الطابور لا يحتوي على عناصر.

    قم أيضاً بإنشاء دالة منشئة (constructor function) باسم NewQueue[T any]() *Queue[T] تعيد مؤشراً (pointer) إلى طابور فارغ تمت تهيئته.

  • main.go: استعرض الـ queue الخاص بك مع أنواع مختلفة بناءً على المدخلات.

    اقرأ مؤشر النوع (int أو string)، ثم اقرأ سلسلة من الأوامر لتنفيذها على الطابور. كل أمر يكون في سطر منفصل:

    • enqueue [value] - إضافة القيمة إلى الطابور.
    • dequeue - إزالة وطباعة العنصر الأمامي (اطبع empty إذا كان الطابور فارغاً).
    • peek - طباعة العنصر الأمامي دون إزالته (اطبع empty إذا كان الطابور فارغاً).
    • size - طباعة الحجم الحالي.

    استمر في قراءة الأوامر حتى تتلقى done.

سيتم توفير المدخلات التالية:

  • السطر 1: مؤشر النوع (int أو string)
  • الأسطر التالية: الأوامر حتى done

على سبيل المثال، إذا كان المدخل:

int
enqueue 10
enqueue 20
enqueue 30
peek
dequeue
size
dequeue
dequeue
dequeue
done

يجب أن يكون مخرجك:

10
10
2
20
30
empty

وإذا كان المدخل:

string
enqueue hello
enqueue world
size
peek
dequeue
peek
done

يجب أن يكون مخرجك:

2
hello
hello
world

يجب أن يعمل الـ queue الخاص بك بشكل متطابق لكل من أنواع الأعداد الصحيحة والنصوص، مما يوضح كيف يمكن لتطبيق عام واحد التعامل مع أنواع ملموسة متعددة مع الحفاظ على سلامة النوع (type safety) الكاملة.

جرّب بنفسك

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// قراءة مؤشر النوع
	scanner.Scan()
	typeIndicator := scanner.Text()
	
	if typeIndicator == "int" {
		// TODO: إنشاء طابور (queue) أعداد صحيحة باستخدام NewQueue[int]()
		// معالجة الأوامر لطابور الأعداد الصحيحة
		
		for scanner.Scan() {
			line := scanner.Text()
			if line == "done" {
				break
			}
			
			parts := strings.SplitN(line, " ", 2)
			command := parts[0]
			
			// TODO: التعامل مع الأوامر: enqueue، dequeue، peek، size
			// لـ enqueue، قم بتحليل قيمة العدد الصحيح من parts[1]
			// لـ dequeue/peek، اطبع "empty" إذا كان الطابور فارغاً
			_ = command
		}
	} else if typeIndicator == "string" {
		// TODO: إنشاء طابور (queue) نصوص باستخدام NewQueue[string]()
		// معالجة الأوامر لطابور النصوص
		
		for scanner.Scan() {
			line := scanner.Text()
			if line == "done" {
				break
			}
			
			parts := strings.SplitN(line, " ", 2)
			command := parts[0]
			
			// TODO: التعامل مع الأوامر: enqueue، dequeue، peek، size
			// لـ enqueue، استخدم قيمة النص من parts[1]
			// لـ dequeue/peek، اطبع "empty" إذا كان الطابور فارغاً
			_ = command
		}
	}
	
	// هذه موجودة هنا لتجنب أخطاء الاستيراد غير المستخدمة (unused import) أثناء التطوير
	_ = strconv.Atoi
	_ = fmt.Println
}

جميع دروس Object Oriented Programming