ال

البنى في Go

1 تمرين

نبذة عن البنى

في 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 أو تبدأ أسماؤها بـ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 مع تهيئة جميع القيم إلى القيمة الصفرية لنوعها، وتُرجع مؤشرًا إليها.

Note

في الغالب لن ترى نسخًا جديدة من البنيات تُنشأ باستخدام الدالة المدمجة new. فضّل دائمًا استخدام قيمة struct الحرفية، أو دالة New مخصّصة، أو أي دالة أخرى توفّرها الحزمة وتساعدك في بناء بنية. واستخدم الدالة المدمجة new لإنشاء نسخ جديدة من البنيات كخيار أخير.

تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة

تعلّم البنى