الأساسيات

البنى Structs

البُنية أو بالانكليزي Struct هو نوع بيانات Datatype مخصص من اختراع المستخدم (المبرمج) used-defined, حيث يحوي مجموعة من الحقول (تُدعى الخصائص Properties).
وتُستخدم البُنى لتجميع البيانات المتشابهة لتشكل وحدة مفردة مستقلة.
وأي شيئ من العالم الواقعي يكون له مجموعة الخصائص, يمكن أن يتم تمثيله ببنية struct, فمثلاً “الأشخاص”, “الموظفون”, “الكتب”, “النباتات”, “الموبايلات”, “العطورات” و…. الخ.

– إنشاء بُنية Struct

من خلال المثال التالي سننشئ بنية Person حيث ستملك بعض الخصائص مثل الاسم الاول والكنية والعمر.
مثال

type Person struct {
	FirstName string
	LastName  string
	Age       int
}

الكلمة المفتاحية type يمكننا من خلالها انشاء نوع بيانات جديد في لغة غو, ثم يتبعها تسمية النوع الذي نريد انشاؤه (في هذه الحالة Person) والكلمة المفتاحية struct هي للاشارة اننا نريد انشاء بنية Structure (يوجد غيرها مثل الواجهات interface)
والبنية تحتوي مجموعة من الحقول داخل قوسين {}, ونسمي هذه الحقول بالخصائص Properties التي تصِف البنية, ولكل خاصية منها “تسمية” ونوع بيانات, فمثلاً خاصية الاسم الأول اسمها FirstName ونوع بياناتها هو string.

وباعتبار أن أول خاصيتين ( الاسم الأول و الكنية) لهما نفس نوع البيانات string فيمكننا تقصير الكود عبر كتابتهما بنفس السطر كالاتي

type Person struct {
	FirstName, LastName string
	Age       int
}

– الاعلان عن بنية واسناد قيم أولية لها

مثل أي نوع بيانات آخر, يمكننا الاعلان عن متغير يحمل نوع بيانات البنية كالاتي

// Declares a variable of type 'Person'
var fadi Person

الكود السابق ينشئ متغير من نوع Person, وبما أننا لم نحدد خصائصه فستأخذ تلقائياً القيمة الصفرية, فمثلاً الخصائص من نوع string ستكون قيمتها فارغة, والقيم من نوع int ستكون قيمتها صفر .

– اسناد القيم الأولية للبنية

يوجد طريقتان لاسناد القيم الأولية لأي بنية كانت, الطريقة الأولى تكون كالاتي

// Initialize a struct by supplying the value of all the struct fields.
var p = Person{"Firas", "Darwish", 25}

في هذه الطريقة يجب إدخال قيم خصائص البنية حسب الترتيب الأصلي للخصائص عندما تم الاعلان عنها في عبارة type Person struct
وأيضاً يجب الملاحظة أنه لايمكن اسناد قيم لبعض الخصائص وترك بعضها الآخر, بل يجب إسناد قيم لجميع الخصائص وإلا سيظهر خطأ شبيه بالاتي

Compiler Error: too few values in struct initializer

والطريقة الثانية لاسناد القيم الأولية للبنية هي عبر ذكر اسم الخاصية وقيمتها (في الطريقة الاولى نذكر القيمة فقط دون اسم الخاصية)

مثال

var p = Person{FirstName: "Firas", LastName: "Darwish", Age: 25}

ويمكن وضع كل خاصية بسطر بشرط وضع فاصلة عشرية بنهاية كل الاسطر كالاتي

var p = Person{
	FirstName: "Firas",
	LastName:  "Darwish",
	Age:       25,
}

وعند استخدام الطريقة الثانية, يمكننا إسناد قيم لبعض الخصائص وترك بعضها الآخر

var p = Person{FirstName: "Firas"}

وحتى الان يكون شكل البرنامج كالاتي

package main

import (
	"fmt"
)

// Defining a struct type
type Person struct {
	FirstName string
	LastName  string
	Age       int
}

func main() {
	// Declaring a variable of a `struct` type

	var p Person 
	fmt.Println(p)

	// Declaring and initializing a struct using a struct literal

	p1 := Person{"Firas", "Darwish", 25}
	fmt.Println("Person1: ", p1)

	// Naming fields while initializing a struct

	p2 := Person{
		FirstName: "John",
		LastName:  "Snow",
		Age:       45,
	}
	fmt.Println("Person2: ", p2)

	// Uninitialized fields are set to their corresponding zero-value

	p3 := Person{FirstName: "Robert"}
	fmt.Println("Person3: ", p3)
}

ونتيجة تنفيذ البرنامج تكون كالاتي

{  0}
Person1:  {Firas Darwish 25}
Person2:  {John Snow 45}
Person3:  {Robert  0}

– التعامل مع خصائص (حقول) البُنية

يمكننا إظهار قيم الخصائص أو التعديل عليها عبر استخدام معامل النقطة ( . )

مثال

package main

import (
	"fmt"
)

type Car struct {
	Name, Model, Color string
	WeightInKg         float64
}

func main() {
	c := Car{
		Name:       "Ferrari",
		Model:      "GTC4",
		Color:      "Red",
		WeightInKg: 1920,
	}

	// Accessing struct fields using the dot operator

	fmt.Println("Car Name: ", c.Name)
	fmt.Println("Car Color: ", c.Color)

	// Assigning a new value to a struct field

	c.Color = "Black"
	fmt.Println("Car: ", c)
}

والنتيجة تكون

Car Name:  Ferrari
Car Color:  Red
Car:  {Ferrari GTC4 Black 1920}

– انشاء متغير من بنية عبر دالة new

يمكننا استخدام الدالة new التي توفرها لغة غو لكي ننشئ متغير من بنية معينة, ويمكن اعتبارها طريقة ثالثة لانشاء متغير من بنية.
مثال

package main

import "fmt"

type Employee struct {
	Id   int
	Name string
}

func main() {
	// You can also get a pointer to a struct using the built-in new() function
	// It allocates enough memory to fit a value of the given struct type, and returns a pointer to it

	pEmp := new(Employee)

	pEmp.Id = 1000
	pEmp.Name = "Sachin"

	fmt.Println(pEmp)
}

والنتيجة

&{1000 Sachin}
ملاحظة: يمكنك تشغيل أكواد وأمثلة لغة غو من خلال GoLang Playground أو GoPlay.Space .

نبذة عن الكاتب

Firas M. Darwish

Software Engineer, PHP/Laravel, C#, GoLang, founder of ArGoLang.com & others ..

شاركنا رأيك :)