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

دالة `init`

جزء من قسم Logic & Flow في رحلة GO على Coddy — الدرس 56 من 68.

دالة init هي دالة خاصة في Go تعمل تلقائياً عند استيراد حزمة (package). على عكس الدوال العادية، لا تقوم باستدعاء init بشكل مباشر - تقوم Go بتنفيذها نيابة عنك أثناء عملية تهيئة الحزمة.

إليك كيفية تعريف دالة init:

package mypackage

import "fmt"

func init() {
    fmt.Println("Package mypackage is being initialized!")
}

تتميز وظيفة init ببعض الخصائص الفريدة: فهي لا تأخذ أي معاملات، ولا تعيد أي قيم، وتعمل قبل بدء وظيفة main. وهذا يجعلها مثالية لإعداد الحالة الأولية، أو تسجيل المكونات، أو أداء مهام الإعداد التي تتم لمرة واحدة والتي تحتاجها الحزمة الخاصة بك.

عندما تقوم باستيراد حزمة تحتوي على دالة init، سترى تأثيراتها على الفور، حتى لو لم تستخدم أيًا من الدوال المصدرة للحزمة. هذا هو السبب في أن نمط استيراد المعرف الفارغ (blank identifier import pattern) الذي تعلمته سابقًا مفيد جدًا - فهو يسمح لك بتشغيل تهيئة الحزمة دون استخدام الكود الخاص بها بشكل مباشر.

quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

challenge icon

التحدي

سهل

قم بإنشاء نظام تهيئة حزم (package initialization system) يوضح كيفية تنفيذ دوال init تلقائياً عند استيراد الحزم. ستقوم ببناء نظام تسجيل (logging system) حيث تقوم الحزم المختلفة بتهيئة نفسها وتتبع تسلسل بدء التشغيل الخاص بها.

ستتلقى مدخلين:

  • سلسلة نصية تحتوي على تعريفات الحزم بتنسيق "package1:message1,package2:message2,package3:message3" (على سبيل المثال، "database:Database connection pool initialized,cache:Cache system ready,logger:Logging system started")
  • سلسلة نصية تحتوي على عمليات البرنامج الرئيسي بتنسيق "operation1,operation2,operation3" (على سبيل المثال، "start_server,process_requests,shutdown")

مهمتك هي:

  1. تحليل المدخل الأول عن طريق تقسيمه عند الفواصل للحصول على تعريفات الحزم الفردية
  2. لكل تعريف حزمة، قم بالتقسيم عند النقطتين الرأسيتين للحصول على اسم الحزمة ورسالة التهيئة
  3. إنشاء شريحة عالمية (global slice) تسمى initLog لتتبع رسائل التهيئة
  4. إنشاء دالة تسمى logInit تأخذ اسم الحزمة والرسالة، ثم تضيف الرسالة المنسقة "[INIT] [package_name]: [message]" إلى شريحة initLog
  5. محاكاة تهيئة الحزمة عن طريق استدعاء logInit لكل حزمة بالترتيب الذي تظهر به في المدخلات
  6. عرض رأس تسلسل التهيئة: "=== PACKAGE INITIALIZATION SEQUENCE ==="
  7. طباعة كل رسالة تهيئة من شريحة initLog
  8. عرض رأس البرنامج الرئيسي: "=== MAIN PROGRAM EXECUTION ==="
  9. طباعة: "All packages initialized successfully"
  10. تحليل المدخل الثاني عن طريق تقسيمه عند الفواصل للحصول على العمليات الفردية
  11. لكل عملية في البرنامج الرئيسي:
    • طباعة: "Executing: [operation]"
    • إضافة رسالة إلى السجل: "[MAIN] Operation: [operation]"
  12. عرض ملخص التنفيذ:
    • "=== EXECUTION SUMMARY ==="
    • "Packages initialized: [number_of_packages]"
    • "Main operations executed: [number_of_operations]"
    • "Total log entries: [total_number_of_log_entries]"
  13. عرض السجل الكامل:
    • "=== COMPLETE EXECUTION LOG ==="
    • طباعة كل إدخال من السجل الكامل (رسائل التهيئة وعمليات البرنامج الرئيسي معاً)
  14. عرض الرسالة النهائية: "Program execution completed - all init functions ran before main"

استخدم حزمة strings لتقسيم سلاسل المدخلات وحزمة fmt للمخرجات المنسقة. يوضح هذا التحدي كيفية تنفيذ دوال init تلقائياً أثناء استيراد الحزمة وتشغيلها دائماً قبل دالة main، مما يجعلها مثالية لمهام إعداد وتهيئة الحزم.

ورقة مرجعية

دالة init هي دالة خاصة في لغة Go تعمل تلقائياً عند استيراد الحزمة:

package mypackage

import "fmt"

func init() {
    fmt.Println("Package mypackage is being initialized!")
}

الخصائص الرئيسية لدوال init:

  • لا تأخذ أي معاملات ولا تعيد أي قيم
  • تعمل تلقائياً أثناء تهيئة الحزمة
  • تُنفذ قبل بدء دالة main
  • مثالية لإعداد الحالة الأولية ومهام الإعداد التي تُنفذ لمرة واحدة
  • يتم استدعاؤها حتى مع عمليات الاستيراد باستخدام المعرف الفارغ (blank identifier)

جرّب بنفسك

package main

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

// شريحة عالمية لتتبع رسائل التهيئة
var initLog []string

func main() {
	reader := bufio.NewReader(os.Stdin)

	// قراءة المدخلات (bufio يتعامل مع الأسطر التي تحتوي على مسافات بشكل صحيح)
	packageDefs, _ := reader.ReadString('\n')
	packageDefs = strings.TrimRight(packageDefs, "\r\n")

	mainOps, _ := reader.ReadString('\n')
	mainOps = strings.TrimRight(mainOps, "\r\n")

	// TODO: اكتب الكود الخاص بك أدناه
	// 1. قم بتحليل packageDefs عن طريق التقسيم عند "," للحصول على إدخالات الحزم الفردية
	// 2. لكل إدخال، قم بالتقسيم عند ":" (بحد أقصى جزأين) للحصول على packageName و message
	// 3. قم بإنشاء دالة logInit(packageName, message string) التي تضيف
	//    "[INIT] [packageName]: message" إلى شريحة initLog العالمية
	// 4. عرض رأس تسلسل التهيئة وجميع إدخالات سجل التهيئة
	// 5. عرض رأس التنفيذ الرئيسي ومعالجة كل عملية من mainOps
	//    - طباعة "Executing: <op>" لكل عملية
	//    - إضافة "[MAIN] Operation: <op>" إلى initLog
	// 6. عرض ملخص التنفيذ (عدد الحزم، عدد العمليات، إجمالي إدخالات السجل)
	// 7. عرض السجل الكامل ورسالة الإكمال النهائية

}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Logic & Flow