المصدرة مقابل غير المصدرة
جزء من قسم المنطق وتدفق التنفيذ في رحلة GO على Coddy. الدرس 52 من 68.
في Go، تتحكم اصطلاحات التسمية البسيطة في إمكانية الوصول إلى المعرّفات (المتغيرات والدوال والأنواع وغيرها). وهذا يحدد ما إذا كان بإمكان التعليمات البرمجية من الحزم الأخرى الوصول إلى معرّفاتك.
المعرّفات المُصدَّرة تبدأ بحرف كبير ويمكن الوصول إليها من الحزم الأخرى. فكّر فيها على أنها «عامة»؛ إذ يمكن لأي شخص يستورد حزمتك استخدامها.
// هذه مُصدَّرة (عامة)
var Name string
func Calculate() int
type Person structالمعرّفات غير المُصدَّرة تبدأ بحرف صغير ولا يمكن الوصول إليها إلا داخل الحزمة نفسها. وهي «خاصة» بحزمتك.
// هذه غير مُصدَّرة (خاصة)
var age int
func helper() string
type config structهذا الاصطلاح في التسمية هو طريقة Go للتحكم في الوصول دون الحاجة إلى كلمات مفتاحية مثل public أو private. عندما تحاول استخدام معرّف غير مُصدّر من حزمة أخرى، ستُصدر Go خطأً في الترجمة لأن هذا المعرّف غير مرئي خارج حزمته.
التحدي
سهلأصلح مشكلات إمكانية الوصول في حزمة Go من خلال تصحيح اصطلاح التسمية للمعرّفات المُصدَّرة وغير المُصدَّرة. ستعمل مع سيناريو محاكاة لحزم متعددة، حيث سُمّيت بعض المعرّفات بطريقة غير صحيحة، ما يسبب أخطاء في التجميع عند الوصول إليها من حزم أخرى.
ستتلقى مُدخلين:
- سلسلة تحتوي على تعريفات الحزم بالتنسيق
"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")
مهمتك هي:
- حلّل المُدخل الأول بتقسيمه عند علامات الأنابيب للحصول على تعريفات الحزم الفردية
- لكل تعريف حزمة، قسّمه عند النقطتين الرأسيتين للحصول على اسم الحزمة ومعرّفاتها
- لكل تعريف معرّف، قسّمه عند النقطتين الرأسيتين للحصول على اسم المعرّف ونوعه وإمكانية الوصول المقصودة إليه
- أنشئ دالة باسم
fixIdentifierNameتأخذ اسم معرّف وإمكانية الوصول المقصودة إليه، وتُعيد الاسم المصحح:- إذا كانت إمكانية الوصول
"public"، فتأكد من أن المعرّف يبدأ بحرف كبير - إذا كانت إمكانية الوصول
"private"، فتأكد من أن المعرّف يبدأ بحرف صغير
- إذا كانت إمكانية الوصول
- اعرض ترويسة تحليل الحزم:
"=== PACKAGE VISIBILITY ANALYSIS ===" - لكل حزمة، اعرض معلوماتها:
"Package: [package_name]"- لكل معرّف في الحزمة:
- إذا كان اسم المعرّف بحاجة إلى تصحيح:
"- [original_name] ([type]) -> [corrected_name] (visibility: [visibility])" - إذا كان اسم المعرّف صحيحًا:
"- [identifier_name] ([type]) (visibility: [visibility]) ✓"
- إذا كان اسم المعرّف بحاجة إلى تصحيح:
- حلّل المُدخل الثاني بتقسيمه عند الفواصل للحصول على محاولات الوصول الفردية
- لكل محاولة وصول، قسّمها عند النقاط للحصول على الحزمة التي تحاول الوصول والمعرّف الذي يجري الوصول إليه
- اعرض ترويسة التحقق من إمكانية الوصول:
"=== ACCESS VALIDATION ===" - لكل محاولة وصول، حدّد ما إذا كان الوصول صالحًا:
- اعثر على الحزمة التي تحتوي على المعرّف
- تحقق مما إذا كان اسم المعرّف المصحح يبدأ بحرف كبير (مُصدَّر)
- إذا كان المعرّف مُصدَّرًا:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✓ ALLOWED (exported)" - إذا كان المعرّف غير مُصدَّر:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✗ DENIED (unexported)" - إذا لم يكن المعرّف موجودًا:
"[accessing_package] accessing unknown.[identifier_name]: ✗ NOT FOUND"(اطبع الكلمةunknownباعتبارها اسم الحزمة؛ وتُحتسب هذه المحاولة محاولة وصول مرفوضة)
- احسب الإحصاءات الموجزة واعرضها:
"=== 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 بإمكانية الوصول إلى الحزم، ويساعدك على فهم الفرق بين المعرّفات المُصدَّرة وغير المُصدَّرة.
جرّب بنفسك
package main
import (
"fmt"
"strings"
)
func main() {
// اقرأ المدخلات
var packageDefinitions string
var accessAttempts string
fmt.Scanln(&packageDefinitions)
fmt.Scanln(&accessAttempts)
// TODO: اكتب الكود الخاص بك أدناه
// أنشئ الدالة fixIdentifierName
// حلّل تعريفات الحزم
// اعرض تحليل الحزم
// حلّل محاولات الوصول
// اعرض نتائج التحقق من الوصول
// احسب الإحصاءات الموجزة واعرضها
// اعرض التوصيات
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس المنطق وتدفق التنفيذ
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)ملخص - الأشكال والسلوكيات6أسلوب Go الاصطلاحي: المجموعات
أسلوب المجموعات في Goإنشاء مجموعةالإضافة إلى مجموعةالتحقق من العضوية في المجموعةالحذف من مجموعةالتكرار عبر عناصر المجموعةمراجعة - أسماء مستخدمين فريدة9الحزم والنطاق
ما هي الحزمة؟المصدرة مقابل غير المصدرةإنشاء حزمة بسيطةالأسماء المستعارة للحزمالمعرف الفارغ `_`دالة `init`ملخص - بناء أداة مساعدةتدرّب بنفسك: مترجم Go عبر الإنترنت