در Go، یک struct دنبالهای از عناصر نامدار به نام فیلد است؛ هر فیلد یک اسم و یک نوع دارد.
اسم هر فیلد باید درون آن ساختار یکتا باشد.
میتوان ساختارها را با کلاسها در الگوی برنامهنویسی شیءگرا مقایسه کرد.
شما با استفاده از «کلیدواژههای» type و struct یک ساختار تازه میسازید و بهصراحت اسم و نوع فیلدها را تعریف میکنید.
برای مثال، در اینجا ساختار Shape را تعریف میکنیم که اسم یک شکل و اندازهی آن را نگه میدارد:
type Shape struct {
name string
size int
}
اسم فیلدها در ساختارها از قرارداد Go پیروی میکند: فیلدهایی که اسمشان با حرف کوچک شروع میشود فقط برای کد موجود در همان پکیج قابل مشاهدهاند، اما فیلدهایی که اسمشان با حرف بزرگ شروع میشود در پکیجهای دیگر هم قابل مشاهدهاند.
وقتی struct را تعریف کردید، باید یک نمونهی تازه بسازید و فیلدها را با اسم فیلدشان، به هر ترتیبی که میخواهید، تعریف کنید:
s := Shape {
name: "Square",
size: 25,
}
برای خواندن یا تغییر فیلدهای یک نمونه، از نماد . استفاده کنید:
// Update the name and the size
s.name = "Circle"
s.size = 35
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: Circle size: 35
فیلدهایی که مقدار اولیهای به آنها نسبت داده نشده باشد، مقدار صفر خود را خواهند داشت. برای مثال:
s := Shape{name: "Circle"}
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: Circle size: 0
میتوانید بدون استفاده از اسم فیلدها هم نمونهای از struct بسازید، به شرطی که فیلدها را به ترتیب تعریف کنید:
s := Shape {
"Oval",
20,
}
اما این نحوهی نگارش کد شکننده به حساب میآید، چون با افزودن یک فیلد ممکن است بشکند، بهویژه وقتی فیلد تازه نوع دیگری داشته باشد.
در مثال زیر یک فیلد اضافه به Shape اضافه میکنیم:
type Shape struct {
name string
description string // new field 'description' added
size int
}
s := Shape{
"Circle",
20,
}
// Since the second field of the struct is now a string and not an int,
// the compiler will throw an error when compiling the program:
// Output: cannot use 20 (type untyped int) as type string in field value
// Output: too few values in Shape{...}
گاهی داشتن توابعی که به ما در ساختن نمونههای ساختار کمک کنند میتواند خوب باشد.
طبق قرارداد، این توابع معمولاً New نامیده میشوند یا اسمشان با New شروع میشود، اما چون فقط توابع معمولی هستند، میتوانید هر اسمی که میخواهید به آنها بدهید.
ممکن است شما را به یاد سازندهها در زبانهای دیگر بیندازند، اما در Go آنها فقط توابع معمولی هستند.
در مثال زیر، یکی از این توابع New برای ساختن یک نمونهی تازه از Shape و تنظیم خودکار مقدار پیشفرضی برای size شکل به کار میرود:
func NewShape(name string) Shape {
return Shape{
name: name,
size: 100, //default-value for size is 100
}
}
NewShape("Triangle")
// => Shape { name: "Triangle", size: 100 }
استفاده از توابع New میتواند مزایای زیر را داشته باشد:
New اغلب در همان پکیجی تعریف میشوند که ساختارهایی را که مقداردهی اولیه میکنند در آن قرار دارند، میتوانند حتی فیلدهای خصوصی ساختار را هم مقداردهی اولیه کنندبرای بررسی عمیقتر این نوع، میتوانید این منابع را ببینید: Go by Example: Structs، A Tour of Go: Structs یا Structures in Go (structs)
new
راه دیگری برای ساختن نمونهی تازه از یک ساختار، استفاده از تابع توکار new است:
s := new(Shape) // s will be of type *Shape (pointer to shape)
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: size: 0
در این مثال، new نمونهای از ساختار Shape میسازد که همهی مقادیرش به مقدار صفر نوعشان مقداردهی شدهاند و اشارهگری به آن برمیگرداند.
در بیشتر موارد، نمونههای تازهای از ساختارها را نخواهید دید که با تابع توکار new ساخته شده باشند.
همیشه ترجیح دهید از یک ساختار تحتاللفظی، یک تابع سفارشی New یا هر تابع دیگری که پکیج در اختیار میگذارد و میتواند به ساختن ساختار کمک کند استفاده کنید.
استفاده از تابع توکار new برای ساختن نمونههای تازه از ساختارها را به عنوان آخرین راهحل در نظر بگیرید.