
راهنمای کاربردی برای توسعهدهندگان Go
یکی از مهمترین مفاهیم در زبان برنامهنویسی Go، ساختارها یا Structها هستند. Struct در Go ابزاری برای تعریف نوع دادهای سفارشی است که میتواند مجموعهای از فیلدهای مرتبط را در کنار هم نگه دارد. Struct پایهایترین راه برای مدلسازی موجودیتها در زبان Go محسوب میشود، زیرا Go برخلاف برخی زبانها از برنامهنویسی شیءگرا با کلاسها پشتیبانی نمیکند و Structها نقش غالباً مشابهی را ایفا میکنند.
در این مقاله با مفهوم Struct، کاربردها، بهترین الگوهای طراحی و نکات پیشرفته آن آشنا میشویم.
Struct در Go یک نوع داده ترکیبی است که از چندین فیلد تشکیل میشود. هر فیلد دارای یک نام و یک نوع است. تعریف یک Struct معمولاً زمانی استفاده میشود که بخواهیم دادههای مرتبط را در یک واحد منطقی گروهبندی کنیم.
type User struct { Name string Age int Email string }
در مثال بالا نوع دادهای جدیدی به نام User تعریف کردهایم که شامل سه فیلد است.
برای ساخت نمونهای از Struct میتوان از روشهای مختلفی استفاده کرد.
u := User{ Name: "Ali", Age: 30, Email: "ali@example.com", }
var u User u.Name = "Sara" u.Age = 25 u.Email = "sara@example.com"
u := &User{ Name: "Reza", }
با استفاده از اشارهگر، دسترسی به فیلدها همچنان با u.Name امکانپذیر است و نیازی به (*u).Name نیست؛ Go به صورت خودکار dereference انجام میدهد.
Go از متدهای متصل به Struct پشتیبانی میکند. این قابلیت یکی از جایگزینهای کلاس در زبان Go محسوب میشود.
func (u User) Info() string { return fmt.Sprintf("%s (%d years old)", u.Name, u.Age) }
Receiver مقداری: یک کپی از Struct دریافت میشود.
Receiver اشارهگری: تغییرات روی نمونه اصلی اعمال میشود.
مثال با pointer receiver:
func (u *User) IncreaseAge() { u.Age++ }
گاهی نیاز نیست Struct را با نام مشخص تعریف کنیم.
user := struct { Name string Age int }{ Name: "Hasan", Age: 40, }
این روش معمولاً برای تستها یا ساخت دادههای موقت استفاده میشود.
Go از وراثت پشتیبانی نمیکند، اما از ترکیب (Composition) استفاده میکند. با Embedding یک Struct در Struct دیگر، فیلدها و متدهای Struct داخلی در Struct بیرونی قابل استفاده میشوند.
type Address struct { City string Phone string } type Employee struct { Name string Address }
اکنون:
e := Employee{Name: "Maryam", Address: Address{City: "Tehran"}} fmt.Println(e.City)
Struct Tagها برای متادیتا بهکار میروند و در عملیاتهایی مانند JSON، پایگاهداده، API و Validation کاربرد دارند.
type Product struct { ID int `json:"id"` Name string `json:"name"` Price int `json:"price,omitempty"` }
ویژگی omitempty باعث میشود فیلدهای خالی در JSON مخفی شوند.
Go کلاس ندارد، اما Struct+Methodها نقش مشابهی ایجاد میکنند.
ویژگیStruct در Goکلاس در زبانهای OOPوراثتنداردداردمتدداردداردسازنده (Constructor)ندارد، اما الگوهای پیشنهادی داردداردEncapsulationنسبی با حروف بزرگ/کوچککامل توسط modifierها
func NewUser(name, email string) *User { return &User{ Name: name, Email: email, Age: 0, } }
اگر تمامی فیلدها قابل مقایسه باشند، Struct نیز قابل مقایسه است.
Structها به صورت contiguous در حافظه ذخیره میشوند، بنابراین ترتیب فیلدها در بهینهسازی حافظه مؤثر است.
در صورتی که فیلدها قابل مقایسه باشند، Struct میتواند کلید یک Map باشد.
Structها در Go پایه اصلی مدلسازی دادهها هستند و امکانات پیشرفتهای همچون متدها، ترکیب، تگها و الگوهای ساخت آبجکت را فراهم میکنند. استفاده درست از Structها باعث طراحی ساختیافته، خوانا و توسعهپذیر در پروژههای Go میشود.