مقدمة: علامات الاقتباس السحرية في كود Go
إذا سبق لك كتابة هياكل (structs) في Go للعمل مع JSON، فمن المحتمل أنك رأيت هذه التركيبات الغريبة:
type User struct { Name string `json:"name"` Age int `json:"age,omitempty"`}هذه العلامات الخلفية الغامضة (`json:"name"`) تُسمى struct tags (وسوم الهياكل). بالنسبة للمبتدئ، تبدو وكأنها سحر أو ضوضاء زائدة. لكنها في الواقع واحدة من أقوى وأروع ميزات Go، والتي تتيح البرمجة الوصفية (meta-programming) بدون وحدات ماكرو معقدة.
في هذه المقالة، سنشرح ما هي struct tags في Go، ولماذا هي ضرورية، وما هي أنواعها، وكيفية استخدامها في المشاريع الحقيقية. ستتوقف عن الخوف من هذه "السلاسل السحرية" وستبدأ في استخدامها بوعي.
ما هي struct tags؟ شرح بسيط
Struct tags هي نصوص حرفية (string literals) تُكتب بعد نوع الحقل في الهيكل. وهي محصورة بين علامات اقتباس خلفية (`) وتتكون من أزواج مفتاح:"قيمة".
من وجهة نظر اللغة، وسوم الهياكل في Go هي مجرد نص. لا يقوم مترجم Go بتحليلها أو التحقق منها. يظهر معناها فقط عندما تقوم أنت (أو مكتبة) بقراءتها من خلال حزمة reflect.
ببساطة: الوسوم هي بيانات وصفية (metadata) ترفقها بحقول الهيكل. يمكن لأجزاء أخرى من برنامجك قراءة هذه البيانات الوصفية وتغيير سلوكها.
لماذا نحتاج struct tags؟ 3 سيناريوهات رئيسية
1. التسلسل/إلغاء التسلسل (JSON، XML، YAML)
هذا هو الاستخدام الأكثر شيوعًا ووضوحًا. تخيل أن لديك هيكل Go وتريد تحويله إلى JSON (أو العكس).
type User struct { ID int `json:"id"` FirstName string `json:"first_name"` LastName string `json:"last_name"` Password string `json:"-"`}
func main() { user := User{ID: 1, FirstName: "إيفان", LastName: "بيتروف", Password: "سر"} jsonData, _ := json.Marshal(user) fmt.Println(string(jsonData)) // الإخراج: {"id":1,"first_name":"إيفان","last_name":"بيتروف"} // كلمة المرور لم تظهر في JSON لأن الوسم json:"-"}بدون الوسوم، ستكون أسماء الحقول ID و FirstName إلخ، وهو ما لا يتوافق مع أسلوب JSON (camelCase مقابل snake_case). وسوم Golang struct لـ JSON تسمح بالتحكم في:
- اسم الحقل في JSON
- تخطي الحقول الفارغة (
omitempty) - استبعاد الحقل من الإخراج (
-) - خيارات متداخلة
2. التحقق من صحة البيانات (Validation)
المكتبات الشائعة مثل go-playground/validator تستخدم وسوم الهياكل Go للتحقق من الصحة. يمكنك ببساطة كتابة القواعد مباشرة في الهيكل:
type SignUpRequest struct { Email string `validate:"required,email"` Password string `validate:"required,min=8,max=32"` Age int `validate:"gte=18,lte=120"`}
func validateUser(user SignUpRequest) error { validate := validator.New() err := validate.Struct(user) return err}هذا مريح للغاية: قواعد التحقق موجودة بجانب البيانات، وليست موزعة في جميع أنحاء الكود. وسوم struct للتحقق من الصحة تجعل الكود موثقًا ذاتيًا.
3. العمل مع قواعد البيانات (ORM)
مكتبات ORM (GORM، Ent، SQLBoiler) تستخدم بنشاط وسوم struct لـ ORM. على سبيل المثال، في GORM:
type Product struct { gorm.Model Code string `gorm:"uniqueIndex;not null"` Price uint `gorm:"default:0"` UserID uint `gorm:"foreignKey:UserID"`}وسوم gorm تحدد الفهارس، القيود، المفاتيح الخارجية وإعدادات الجدول الأخرى. هذا يلغي الحاجة إلى كتابة ترحيلات منفصلة.