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

المصدرة مقابل غير المصدرة

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

في لغة Go، يتم التحكم في رؤية المعرفات (المتغيرات، الدوال، الأنواع، إلخ) من خلال اتفاقية تسمية بسيطة. يحدد هذا ما إذا كان بإمكان الكود من الحزم الأخرى الوصول إلى معرفاتك.

المعرفات المصدرة تبدأ بحرف كبير ويمكن الوصول إليها من حزم أخرى. فكر فيها على أنها "public" - حيث يمكن استخدامها من قبل أي شخص يقوم باستيراد حزمتك.

// هذه العناصر مُصدّرة (عامة)
var Name string
func Calculate() int
type Person struct

المعرفات غير المصدرة تبدأ بحرف صغير ويمكن الوصول إليها فقط داخل نفس الحزمة. هذه تعتبر "خاصة" بحزمتك.

// هذه غير مُصدّرة (خاصة)
var age int
func helper() string
type config struct

تعد اتفاقية التسمية هذه هي طريقة لغة Go للتحكم في الوصول دون الحاجة إلى كلمات مفتاحية مثل public أو private. عندما تحاول استخدام معرّف غير مُصدّر من حزمة أخرى، ستعطيك Go خطأ في التجميع (compilation error) لأن ذلك المعرّف غير مرئي خارج حزمته.

quiz iconاختبر نفسك

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

quiz iconاختبر نفسك

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

quiz iconاختبر نفسك

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

challenge icon

التحدي

سهل

قم بإصلاح مشكلات الرؤية (visibility) في حزمة Go عن طريق تصحيح اصطلاح التسمية للمعرفات المصدرة (exported) وغير المصدرة (unexported). ستعمل مع سيناريو محاكاة متعدد الحزم حيث تمت تسمية بعض المعرفات بشكل غير صحيح، مما يتسبب في أخطاء برمجية عند محاولة الوصول إليها من حزم أخرى.

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

  • سلسلة نصية تحتوي على تعريفات الحزم بالتنسيق "package_name:identifier1:type1:visibility1,identifier2:type2:visibility2|package_name:identifier1:type1:visibility1" (مثال: "utils:helper:function:private,Calculate:function:public|main:name:variable:private,Version:variable:public")
  • سلسلة نصية تحتوي على محاولات الوصول بالتنسيق "accessing_package.identifier1,accessing_package.identifier2,accessing_package.identifier3" (مثال: "main.helper,main.Calculate,utils.Version")

مهمتك هي:

  1. تحليل المدخل الأول عن طريق التقسيم عند الرموز "|" للحصول على تعريفات الحزم الفردية
  2. لكل تعريف حزمة، قم بالتقسيم عند النقطتين الرأسيتين ":" للحصول على اسم الحزمة ومعرفاتها
  3. لكل تعريف معرف، قم بالتقسيم عند النقطتين الرأسيتين ":" للحصول على اسم المعرف، ونوعه، والرؤية المقصودة له
  4. إنشاء دالة تسمى fixIdentifierName تأخذ اسم المعرف والرؤية المقصودة، وتعيد الاسم المصحح:
    • إذا كانت الرؤية "public"، فتأكد من أن المعرف يبدأ بحرف كبير (capital letter)
    • إذا كانت الرؤية "private"، فتأكد من أن المعرف يبدأ بحرف صغير (lowercase letter)
  5. عرض ترويسة تحليل الحزمة: "=== PACKAGE VISIBILITY ANALYSIS ==="
  6. لكل حزمة، اعرض معلومات الحزمة:
    • "Package: [package_name]"
    • لكل معرف في الحزمة:
      • إذا كان اسم المعرف يحتاج إلى إصلاح: "- [original_name] ([type]) -> [corrected_name] (visibility: [visibility])"
      • إذا كان اسم المعرف صحيحاً: "- [identifier_name] ([type]) (visibility: [visibility]) ✓"
    • تحليل المدخل الثاني عن طريق التقسيم عند الفواصل للحصول على محاولات الوصول الفردية
    • لكل محاولة وصول، قم بالتقسيم عند النقاط للحصول على الحزمة التي تحاول الوصول والمعرف الذي يتم الوصول إليه
    • عرض ترويسة التحقق من الوصول: "=== ACCESS VALIDATION ==="
    • لكل محاولة وصول، حدد ما إذا كان الوصول صالحاً:
      • ابحث عن الحزمة التي تحتوي على المعرف
      • تحقق مما إذا كان اسم المعرف المصحح يبدأ بحرف كبير (مصدر/exported)
      • إذا كان المعرف مصدراً: "[accessing_package] accessing [target_package].[corrected_identifier_name]: ✓ ALLOWED (exported)"
      • إذا كان المعرف غير مصدر: "[accessing_package] accessing [target_package].[corrected_identifier_name]: ✗ DENIED (unexported)"
      • إذا كان المعرف غير موجود: "[accessing_package] accessing [target_package].[identifier_name]: ✗ NOT FOUND"
    • حساب وعرض الإحصائيات الملخصة:
      • "=== SUMMARY ==="
      • "Total packages analyzed: [number_of_packages]"
      • "Total identifiers processed: [total_number_of_identifiers]"
      • "Identifiers requiring fixes: [number_of_identifiers_that_needed_fixing]"
      • "Access attempts: [number_of_access_attempts]"
      • "Allowed accesses: [number_of_allowed_accesses]"
      • "Denied accesses: [number_of_denied_accesses]"
    • عرض التوصيات النهائية:
      • إذا كانت هناك معرفات تتطلب إصلاحات: "Recommendation: Fix identifier naming to follow Go conventions"
      • إذا كانت جميع المعرفات صحيحة: "All identifiers follow proper Go naming conventions"

استخدم حزمة strings لتقسيم سلاسل الإدخال، وحزمة fmt للمخرجات المنسقة، ودوال معالجة النصوص للتحقق من أسماء المعرفات وتعديلها. يوضح هذا التحدي كيف يتحكم اصطلاح التسمية في Go في رؤية الحزمة ويساعدك على فهم الفرق بين المعرفات المصدرة وغير المصدرة.

ورقة مرجعية

تتحكم لغة Go في الرؤية (visibility) من خلال اصطلاحات التسمية دون استخدام كلمات مفتاحية صريحة مثل public أو private.

المعرفات المصدرة (Exported identifiers) تبدأ بحرف كبير ويمكن الوصول إليها من الحزم الأخرى:

// هذه معرفات مصدرة (عامة)
var Name string
func Calculate() int
type Person struct

المعرفات غير المصدرة (Unexported identifiers) تبدأ بحرف صغير ولا يمكن الوصول إليها إلا داخل نفس الحزمة:

// هذه معرفات غير مصدرة (خاصة)
var age int
func helper() string
type config struct

تؤدي محاولة الوصول إلى المعرفات غير المصدرة من حزم أخرى إلى حدوث أخطاء في الترجمة (compilation errors).

جرّب بنفسك

package main

import (
	"fmt"
	"strings"
)

func main() {
	// قراءة المدخلات
	var packageDefinitions string
	var accessAttempts string
	fmt.Scanln(&packageDefinitions)
	fmt.Scanln(&accessAttempts)

	// TODO: اكتب الكود الخاص بك أدناه
	
	// إنشاء دالة fixIdentifierName
	
	// تحليل تعريفات الحزم (package definitions)
	
	// عرض تحليل الحزم
	
	// تحليل محاولات الوصول
	
	// عرض التحقق من الوصول
	
	// حساب وعرض الإحصائيات الملخصة
	
	// عرض التوصيات
}
quiz iconاختبر نفسك

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

جميع دروس Logic & Flow