تعلم كيفية هيكلة كود Go بالطريقة الصحيحة: من مشاريع الملف الواحد إلى الحزم والوحدات الداخلية والاستيرادات المناسبة، موضحة بمثال آلة حاسبة.تعلم كيفية هيكلة كود Go بالطريقة الصحيحة: من مشاريع الملف الواحد إلى الحزم والوحدات الداخلية والاستيرادات المناسبة، موضحة بمثال آلة حاسبة.

كيفية تنظيم مشاريع Go الخاصة بك كمحترف

2025/10/06 11:36

\ عندما بدأت تعلم Go، كان أحد أول الأسئلة التي طرحتها هو:

"كيف أقوم فعلياً بهيكلة الكود الخاص بي؟"

في لغات مثل C، من الشائع وضع كل شيء في ملف واحد، أو ربما فصل ملفات الرأس والتنفيذ. لكن في Go، هيكل المشروع أمر مهم: فهو يؤثر على مدى سهولة توسيع واختبار ومشاركة الكود الخاص بك. في هذا المقال، سأشرح سبب أهمية الهيكلة، وكيفية الوصول إلى الدوال من ملفات مختلفة، وأفضل الممارسات التي أتعلمها أثناء تقدمي.


أبسط برنامج Go

يمكن أن يعيش برنامج Go بالكامل في ملف واحد:

package main  import "fmt"  func main() {   fmt.Println("2 + 2 =", 2+2) } 

هذا يعمل بشكل جيد لـ "hello world" أو التجارب السريعة.

ولكن بمجرد إضافة المزيد من الوظائف (الطرح، الضرب، القسمة...)، يصبح الملف فوضوياً وبالكاد قابلاً للتوسع.

هنا يأتي دور الحزم و المجلدات في Go.


مقدمة عن الحزم

في Go، كل ملف ينتمي إلى حزمة.

حسب الاتفاقية:

  • main → برنامج قابل للتنفيذ
  • أخرى (مثل الآلة الحاسبة، الأدوات المساعدة، إلخ) → منطق قابل لإعادة الاستخدام

إليك كيف قمت بتقسيم مشروع الآلة الحاسبة:

calculator/ │ ├── main.go └── calculator/     └── operations.go 

\

  • main.go → يتعامل مع الإدخال/الإخراج
  • operations.go → يحدد دوال مثل Add، Subtract، إلخ.

مثال: operations.go

package calculator  func Add(a, b int) int {   return a + b }  func Subtract(a, b int) int {   return a - b }  func Multiply(a, b int) int {   return a * b }  func Divide(a, b int) (int, error) {   if b == 0 {     return 0, fmt.Errorf("cannot divide by zero")   }   return a / b, nil } 

مثال: main.go

package main  import (   "fmt"   "GoLang-progress/calculator" )  func main() {   fmt.Println("2 + 3 =", calculator.Add(2, 3))   fmt.Println("10 - 4 =", calculator.Subtract(10, 4))   fmt.Println("6 * 7 =", calculator.Multiply(6, 7))    result, err := calculator.Divide(8, 0)   if err != nil {     fmt.Println("Error:", err)   } else {     fmt.Println("8 / 0 =", result)   } } 

لاحظ كيف أن main.go أصبح الآن نظيفاً: فهو لا يقلق بشأن الرياضيات نفسها، بل فقط كيفية استخدامها.


الوصول إلى الدوال من ملفات مختلفة

سؤال شائع للمبتدئين:

"كيف أستدعي دالة من ملف أو مجلد آخر؟"

في المستودع الخاص بي، قمت بهيكلته بهذه الطريقة:

calculator/ │ ├── main.go └── internal/     └── calc/         └── operations.go 

هنا، توجد دوال الرياضيات تحت internal/calc.

operations.go (داخل internal/calc)

\

package calc  import "fmt"  func Add(a, b int) int {   return a + b }  func Divide(a, b int) (int, error) {   if b == 0 {     return 0, fmt.Errorf("cannot divide by zero")   }   return a / b, nil } 

main.go (استيراد internal/calc)

\

package main  import (   "fmt"   "github.com/turman17/GoLang-progress/calculator/internal/calc" )  func main() {   fmt.Println("2 + 3 =", calc.Add(2, 3))    result, err := calc.Divide(10, 0)   if err != nil {     fmt.Println("Error:", err)   } else {     fmt.Println("10 / 2 =", result)   } } 

لماذا مسار الاستيراد هذا مطلوب

يجب أن يتطابق الاستيراد الخاص بك مع مسار الوحدة من go.mod بالإضافة إلى مسار المجلد.

في المستودع الخاص بك، يحتوي go.mod على:

module github.com/turman17/GoLang-progress 

كود الآلة الحاسبة الذي تريد استخدامه موجود في المجلد:

calculator/internal/calc 

لذا فإن مسار الاستيراد الكامل هو:

github.com/turman17/GoLang-progress/calculator/internal/calc 

بعض الملاحظات المهمة

  • اسم المجلد ≠ اسم الحزمة → المجلد هو internal/calc، لكن الحزمة بداخله معلنة كـ package calc.
  • الاستيرادات تستخدم مسار الوحدة → ابدأ دائمًا بـ github.com/… إذا كان ذلك في go.mod الخاص بك.
  • Internal خاص → الحزم تحت /internal يمكن استيرادها فقط بواسطة الكود داخل نفس الوحدة.

الأخطاء الشائعة والإصلاحات

❌ import "GoLang-progress/calculator/internal/calc"

→ اسم مؤسسة/مستخدم GitHub مفقود. يجب استخدام المسار الكامل.

❌ import "github.com/turman17/GoLang-progress/internal/calc"

→ دليل calculator مفقود في المسار.

❌ go: module not found errors

→ تأكد من أن go.mod يحتوي على module github.com/turman17/GoLang-progress وقم بتشغيل go mod tidy.


قائمة تحقق سريعة

  • go.mod يحتوي على سطر الوحدة الصحيح
  • الدليل هو calculator/internal/calc مع حزمة calc بداخله
  • main.go يستورد github.com/turman17/GoLang-progress/calculator/internal/calc
  • البناء من جذر الوحدة:

\

go run ./calculator 

أو

go build ./calculator 

توسيع الهيكل

مع نمو المشاريع، غالباً ما سترى هذا النمط:

project-name/ │ ├── cmd/        → executables (main entrypoints) ├── internal/   → private code (not for external use) ├── pkg/        → reusable packages ├── api/        → API definitions (gRPC, OpenAPI, etc.) └── go.mod 

بالنسبة للمبتدئين، قد يكون هذا مبالغاً فيه. ولكن عندما تنتقل إلى تطبيقات الويب أو الخدمات أو أدوات MLOps، يصبح هذا التخطيط ضرورياً.


أفضل الممارسات التي أتعلمها

  • الحفاظ على الحزم صغيرة ومركزة
  • استخدام أسماء ذات معنى (calc، parser، storage)
  • تجنب المبالغة في الهندسة — ابدأ ببساطة، وأعد الهيكلة لاحقاً
  • تجنب التبعيات الدائرية (Go يفرض هذا)

دروس من مشروع الآلة الحاسبة

  • فصل المنطق (operations.go) عن نقطة الدخول (main.go) يجعل الاختبار أسهل.
  • معالجة الأخطاء (مثل القسمة على صفر) يجب أن تكون صريحة.
  • مسارات الاستيراد مهمة حقاً — خاصة عند استخدام internal.

سأواصل مشاركة ما أتعلمه أثناء استكشافي لـ Go من أجل MLOps وتطوير الواجهة الخلفية. القادم: معالجة الأخطاء والاختبار في Go.

\ 👉 تحقق من المستودع الخاص بي هنا: https://github.com/turman17/GoLang-progress

وترقبوا المقال القادم!

إخلاء مسؤولية: المقالات المُعاد نشرها على هذا الموقع مستقاة من منصات عامة، وهي مُقدمة لأغراض إعلامية فقط. لا تُظهِر بالضرورة آراء MEXC. جميع الحقوق محفوظة لمؤلفيها الأصليين. إذا كنت تعتقد أن أي محتوى ينتهك حقوق جهات خارجية، يُرجى التواصل عبر البريد الإلكتروني service@support.mexc.com لإزالته. لا تقدم MEXC أي ضمانات بشأن دقة المحتوى أو اكتماله أو حداثته، وليست مسؤولة عن أي إجراءات تُتخذ بناءً على المعلومات المُقدمة. لا يُمثل المحتوى نصيحة مالية أو قانونية أو مهنية أخرى، ولا يُعتبر توصية أو تأييدًا من MEXC.
مشاركة الرؤى

قد يعجبك أيضاً