فهم الأنواع البيانية في Go

مقدمة

تحدد أنواع البيانات أنواع القيم التي ستخزنها المتغيرات المعينة عند كتابة برنامج. كما تحدد نوع البيانات أيضًا العمليات التي يمكن إجراؤها على البيانات.

في هذه المقالة، سنتناول أهم أنواع البيانات الأصلية في لغة Go. هذا ليس تحقيقًا شاملاً لأنواع البيانات، ولكنه سيساعدك على التعرف على الخيارات المتاحة لديك في Go. فهم بعض الأنواع الأساسية للبيانات سيمكنك من كتابة كود أكثر وضوحًا ويعمل بكفاءة.

خلفية

إحدى الطرق للتفكير في أنواع البيانات هي النظر إلى أنواع البيانات المختلفة التي نستخدمها في العالم الحقيقي. مثال على البيانات في العالم الحقيقي هي الأرقام: قد نستخدم الأعداد الصحيحة (0، 1، 2، …)، والأعداد الصحيحة (…، -1، 0، 1، …)، والأعداد غير المنطقية (π)، على سبيل المثال.

عادةً، في الرياضيات، يمكننا دمج الأرقام من أنواع مختلفة والحصول على نوع من الإجابات. قد نرغب في إضافة 5 إلى π، على سبيل المثال:

5 + π

يمكننا إما الاحتفاظ بالمعادلة كإجابة لحساب العدد غير المنطقي، أو تقريب π إلى رقم بعدد مختصر من المنازل العشرية، ثم جمع الأرقام معًا:

5 + π = 5 + 3.14 = 8.14 

لكن إذا بدأنا نحاول تقييم الأرقام باستخدام نوع بيانات آخر، مثل الكلمات، تبدأ الأمور في أن تصبح أقل منطقية. كيف يمكننا حل المعادلة التالية؟

shark + 8

بالنسبة للكمبيوترات، كل نوع بيانات مختلف تمامًا—مثل الكلمات والأرقام. نتيجة لذلك، يجب أن نكون حذرين بشأن كيفية استخدامنا لأنواع البيانات المختلفة لتعيين القيم وكيفية التلاعب بها من خلال العمليات.

الأعداد الصحيحة

كما في الرياضيات، الأعداد الصحيحة integers في برمجة الكمبيوتر هي أرقام كاملة يمكن أن تكون موجبة أو سالبة أو 0 (…, -1, 0, 1, …). في Go، يُعرف العدد الصحيح باسم int. كما هو الحال مع لغات البرمجة الأخرى، يجب عدم استخدام الفواصل في الأرقام التي تتكون من أربعة أرقام أو أكثر، لذا عندما تكتب 1,000 في برنامجك، اكتبها كـ 1000.

يمكننا طباعة عدد صحيح بطريقة بسيطة مثل هذه:

fmt.Println(-459)
Output
-459

أو، يمكننا تعريف متغير، وهو في هذه الحالة رمز للرقم الذي نستخدمه أو نتلاعب به، كالتالي:

var absoluteZero int = -459
fmt.Println(absoluteZero)
Output
-459

يمكننا أيضًا إجراء العمليات الحسابية باستخدام الأعداد الصحيحة في Go. في الكتلة البرمجية التالية، سنستخدم عامل التعيين := لتعريف وإنشاء المتغير sum:

sum := 116 - 68
fmt.Println(sum)
Output
48

كما يظهر في الناتج، عامل الرياضيات - طرح العدد الصحيح 68 من 116، مما أدى إلى 48. ستتعلم المزيد عن تعريف أنواع البيانات للمتغيرات في قسم تعريف أنواع البيانات للمتغيرات.

يمكن استخدام الأعداد الصحيحة في العديد من الطرق داخل برامج Go. عندما تستمر في تعلم Go، ستحصل على الكثير من الفرص للعمل مع الأعداد الصحيحة وبناءً على معرفتك لهذا النوع من البيانات.

الأعداد العشرية

العدد العشري أو العدد العائم أو العائم يستخدم لتمثيل الأعداد الحقيقية التي لا يمكن التعبير عنها كأعداد صحيحة. تشمل الأعداد الحقيقية جميع الأعداد النسبية واللاعقلانية، ولذلك يمكن أن تحتوي الأعداد العشرية على جزء كسري، مثل 9.0 أو -116.42. لأغراض التفكير في عدد عشري في برنامج Go، فهو عدد يحتوي على نقطة عشرية.

كما فعلنا مع الأعداد الصحيحة، يمكننا طباعة عدد عشري بطريقة بسيطة مثل هذه:

fmt.Println(-459.67)
Output
-459.67

يمكننا أيضًا تعريف متغير يمثل عددًا عشريًا، كالتالي:

absoluteZero := -459.67
fmt.Println(absoluteZero)
Output
-459.67

تمامًا مثل الأعداد الصحيحة، يمكننا أيضًا إجراء العمليات الحسابية مع الأعداد العشرية في Go:

var sum = 564.0 + 365.24
fmt.Println(sum)
Output
929.24

مع الأعداد الصحيحة والأعداد العشرية، من المهم أن نتذكر أن 3 لا يساوي 3.0، حيث إن 3 تشير إلى عدد صحيح بينما 3.0 تشير إلى عدد عشري.

أحجام أنواع الأعداد

بالإضافة إلى التمييز بين الأعداد الصحيحة والأعداد العشرية، يحتوي Go على نوعين من البيانات العددية يتم التمييز بينهما بناءً على طبيعة أحجامهما الثابتة أو الديناميكية. النوع الأول هو نوع مستقل عن الأثرياء، مما يعني أن حجم البيانات بالبتات لا يتغير، بغض النظر عن الجهاز الذي يعمل عليه الكود.

معظم الأثرياء النظامية اليوم إما 32 بت أو 64 بت. على سبيل المثال، قد تقوم بالتطوير لجهاز كمبيوتر محمول حديث من نوع Windows، حيث يعمل نظام التشغيل على بنية 64 بت. ومع ذلك، إذا كنت تقوم بالتطوير لجهاز مثل ساعة اللياقة البدنية، فقد تكون تعمل مع بنية 32 بت. إذا استخدمت نوعًا مستقلًا عن الأثرياء مثل int32، بغض النظر عن البنية التي تقوم بالترجمة لها، سيكون للنوع حجم ثابت.

النوع الثاني هو نوع خاص بالتنفيذ. في هذا النوع، يمكن أن يختلف حجم البت بناءً على البنية التي يتم بناء البرنامج عليها. على سبيل المثال، إذا استخدمنا نوع int، عندما يتم ترجمة Go لبنية 32 بت، سيكون حجم نوع البيانات 32 بت. إذا تم ترجمة البرنامج لبنية 64 بت، سيكون المتغير بحجم 64 بت.

بالإضافة إلى أن الأنواع لها أحجام مختلفة، فإن أنواع الأعداد الصحيحة تأتي أيضًا في نوعين أساسيين: موجبة وسالبة. int8 هو عدد صحيح موجب، ويمكن أن يكون له قيمة من -128 إلى 127. uint8 هو عدد صحيح سالب، ويمكن أن يكون له قيمة موجبة فقط من 0 إلى 255.

النطاقات تستند إلى حجم البت. بالنسبة للبيانات الثنائية، يمكن لـ 8 بت تمثيل ما مجموعه 256 قيمة مختلفة. نظرًا لأن نوع int يحتاج إلى دعم كل من القيم الموجبة والسالبة، فإن عدد صحيح 8 بت (int8) سيكون له نطاق من -128 إلى 127، لمجموع 256 قيمة ممكنة فريدة.

تتضمن Go أنواع صحيحة غير معتمدة على الهندسة:

uint8       unsigned  8-bit integers (0 to 255)
uint16      unsigned 16-bit integers (0 to 65535)
uint32      unsigned 32-bit integers (0 to 4294967295)
uint64      unsigned 64-bit integers (0 to 18446744073709551615)
int8        signed  8-bit integers (-128 to 127)
int16       signed 16-bit integers (-32768 to 32767)
int32       signed 32-bit integers (-2147483648 to 2147483647)
int64       signed 64-bit integers (-9223372036854775808 to 9223372036854775807)

تأتي الأعداد العشرية والأعداد المركبة أيضًا بأحجام متنوعة:

float32     IEEE-754 32-bit floating-point numbers
float64     IEEE-754 64-bit floating-point numbers
complex64   complex numbers with float32 real and imaginary parts
complex128  complex numbers with float64 real and imaginary parts

هناك أيضًا زوج من أنواع الأرقام المستعارة، التي تعين أسماء مفيدة لأنواع بيانات معينة:

byte        alias for uint8
rune        alias for int32

الغرض من الاسم المستعار byte هو توضيح عندما يستخدم برنامجك البايتات كقياس شائع في عناصر سلسلة الأحرف، على عكس الأعداد الصحيحة الصغيرة غير المرتبطة بقياس بيانات البايت. على الرغم من أن byte و uint8 متطابقان بمجرد تجميع البرنامج، إلا أن byte يستخدم غالبًا لتمثيل بيانات الأحرف في شكل رقمي، بينما يهدف uint8 إلى أن يكون رقمًا في برنامجك.

الاسم المستعار rune مختلف قليلاً. حيث إن byte و uint8 هما نفس البيانات تمامًا، يمكن أن يكون rune بايت واحد أو أربعة بايت، نطاق يحدده int32. يستخدم rune لتمثيل حرف Unicode، بينما يمكن تمثيل أحرف ASCII فقط بواسطة نوع البيانات int32.

بالإضافة إلى ذلك، تحتوي Go على أنواع معينة بواسطة التنفيذ:

uint     unsigned, either 32 or 64 bits
int      signed, either 32 or 64 bits
uintptr  unsigned integer large enough to store the uninterpreted bits of a pointer value 

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

اختيار أنواع البيانات العددية

اختيار الحجم الصحيح يتعلق عادة بالأداء للهندسة المستهدفة التي تقوم بالبرمجة لها أكثر من حجم البيانات التي تعمل عليها. ومع ذلك، دون الحاجة إلى معرفة التداعيات المحددة للأداء لبرنامجك، يمكنك اتباع بعض هذه الإرشادات الأساسية عند البدء لأول مرة.

كما تمت مناقشته سابقًا في هذه المقالة، هناك أنواع مستقلة عن الهندسة وأنواع محددة للتنفيذ. بالنسبة للبيانات الصحيحة، من الشائع في Go استخدام أنواع التنفيذ مثل int أو uint بدلاً من int64 أو uint64. سيؤدي هذا عادةً إلى أسرع سرعة معالجة للهندسة المستهدفة. على سبيل المثال، إذا استخدمت int64 وقمت بالترجمة إلى هندسة 32 بت، فسيستغرق معالجة هذه القيم وقتًا على الأقل ضعفًا من الوقت الذي يتطلبه نقل البيانات عبر الهندسة. إذا استخدمت int بدلاً من ذلك، فسيحدد البرنامجه على أنه حجم 32 بت لهندسة 32 بت، وسيكون أسرع بكثير في المعالجة.

إذا كنت تعرف أنك لن تتجاوز نطاقًا حجميًا معينًا، فيمكن أن يزيد اختيار نوع مستقل عن الهندسة سرعة البرنامج ويقلل من استهلاك الذاكرة. على سبيل المثال، إذا كنت تعرف أن بياناتك لن تتجاوز القيمة 100، وستكون عددًا موجبًا فقط، فإن اختيار uint8 سيجعل برنامجك أكثر كفاءة لأنه سيتطلب ذاكرة أقل.

وما ننظر اليه الآن هو بعض أحدث المجالات للأنواع الرقمية، لنرى ماذا سيحدث إذا تجاوزنا هذه المجالات في برنامجنا.

التجاوز مقابل التدوير

يمكن للغوص أن يتسبب في تجاوز رقم وتدويره عندما تحاول تخزين قيمة أكبر من النوع المخصص للبرنامج، وهذا يعتمد على ما إذا كان القيمة قد يتم حسابها في الوقت المنصرم أو في الوقت الفعال. يحدث خطأ في الوقت المنصرم عندما يكتشف البرنامج خطأً أثناء محاولة بناء البرنامج. يحدث خطأ في الوقت الفعال بعد تجميع البرنامج، بينما يتم تنفيذه.

في المثال التالي ، نضع maxUint32 بقيمته الأقصية:

package main

import "fmt"

func main() {
	var maxUint32 uint32 = 4294967295 // حجم الuint32 الأقصي
	fmt.Println(maxUint32)
}

سيتم تجاوز التكوين وتشغيله بنتيجة التالية:

Output
4294967295

إذا أضافنا 1 إلى القيمة في الوقت الفعال، فسيتدوير القيمة الي 0:

Output
0

على الجانب الآخر، فلنغير البرنامج لتضيف 1 إلى المتغير حين تحدده، قبل التكوين:

package main

import "fmt"

func main() {
	var maxUint32 uint32 = 4294967295 + 1
	fmt.Println(maxUint32)

}

في الوقت المنصرم، إذا أدى المخترع إلى تحديد أن قيمة ستكون أكبر مما يمكن أن تستولي عليها النوع المخصص، فيلوجر خطأ التجاوز. هذا يعني أن قيمة الحساب المحاسبة تكون أكبر من النوع المخصص الذي أعلنت عنه.

لأن المخترع يمكنه تحديد أنه سيتجاوز القيمة، سيثمن خطأ حالياً:

Output
prog.go:6:36: constant 4294967296 overflows uint32

فهم حدود بياناتك سيساعدك على تجنب الأخطاء المحتملة في برنامجك في المستقبل.

الآن بعد أن تناولنا أنواع الأرقام، دعونا ننظر في كيفية تخزين القيم المنطقية.

القيم المنطقية

نوع البيانات منطقي يمكن أن يكون أحد قيمتين، إما true أو false، ويُعرّف بـ bool عندما يتم تعريفه كنوع بيانات. تُستخدم القيم المنطقية لتمثيل القيم الحقيقية المرتبطة بفرع المنطق من الرياضيات، الذي يعلم الخوارزميات في علوم الكمبيوتر.

القيم true و false ستكون دائمًا بأحرف صغيرة t و f على التوالي، حيث إنها معرّفات مُعلنة مسبقًا في Go.

العديد من العمليات في الرياضيات تعطينا إجابات تُقيّم إما صحيحة أو خاطئة:

  • أكبر من
    • 500 > 100 true
    • 1 > 5 false
  • أقل من
    • 200 < 400 true
    • 4 < 2 false
  • مساوي
    • 5 = 5 true
    • 500 = 400 false

كما هو الحال مع الأرقام، يمكننا تخزين قيمة منطقية في متغير:

myBool := 5 > 8

بعد ذلك، يمكننا طباعة القيمة المنطقية باستدعاء دالة fmt.Println():

fmt.Println(myBool)

بما أن 5 ليس أكبر من 8، سنحصل على الناتج التالي:

Output
false

عندما تكتب المزيد من البرامج في Go، ستصبح أكثر دراية بكيفية عمل القيم المنطقية وكيف يمكن للدوال والعمليات المختلفة التي تُقيّم إلى إما true أو false تغيير مسار البرنامج.

السلاسل النصية

السلسلة النصية هي تسلسل من واحد أو أكثر من الأحرف (أحرف، أرقام، رموز) ويمكن أن تكون إما ثابتة أو متغيرة. توجد السلاسل داخل إما علامات الاقتباس المفردة ` أو علامات الاقتباس المزدوجة " في Go ولها خصائص مختلفة بناءً على الاقتباسات التي تستخدمها.

إذا استخدمت الاقتباسات المفردة، فأنت تقوم بإنشاء سلسلة نصية خام. إذا استخدمت الاقتباسات المزدوجة، فأنت تقوم بإنشاء سلسلة نصية مفسرة.

السلاسل النصية الخام

السلاسل النصية الخام هي تسلسلات أحرف بين علامات الاقتباس المفردة، والتي يطلق عليها غالبًا العلامات العكسية. داخل الاقتباسات، أي حرف سيظهر تمامًا كما هو معروض بين العلامات العكسية، باستثناء الحرف العكسي نفسه.

a := `Say "hello" to Go!`
fmt.Println(a)
Output
Say "hello" to Go!

عادةً ما يتم استخدام شرطات مائلة إلى الوراء لتمثيل الأحرف الخاصة في السلاسل. على سبيل المثال، في سلسلة مفسرة، \n ستمثل سطرًا جديدًا في السلسلة. ومع ذلك، لا يحمل الخط المائل العكسي أي معنى خاص داخل السلاسل النصية الأولية:

a := `Say "hello" to Go!\n`
fmt.Println(a)

نظرًا لعدم وجود معنى خاص للخط المائل العكسي في السلسلة النصية، سيتم طباعة قيمة \n بدلاً من إنشاء سطر جديد:

Output
Say "hello" to Go!\n

يمكن أيضًا استخدام السلاسل النصية الأولية لإنشاء سلاسل متعددة الأسطر:

a := `This string is on 
multiple lines
within a single back 
quote on either side.`
fmt.Println(a)
Output
This string is on multiple lines within a single back quote on either side.

في الكتل البرمجية السابقة، تم نقل الأسطر الجديدة حرفيًا من المدخلات إلى المخرجات.

السلاسل النصية المفسرة

السلاسل النصية المفسرة هي تسلسلات الأحرف بين علامتي اقتباس مزدوجتين، كما في "bar". داخل الاقتباسات، يمكن أن يظهر أي حرف باستثناء السطر الجديد والاقتباسات المزدوجة غير المهروسة. لإظهار الاقتباسات المزدوجة في سلسلة نصية مفسرة، يمكنك استخدام الخط المائل العكسي كحرف هروب، كالتالي:

a := "Say \"hello\" to Go!"
fmt.Println(a)
Output
Say "hello" to Go!

ستستخدم تقريبًا دائمًا السلاسل النصية المفسرة لأنها تسمح بأحرف الهروب داخلها. لمزيد من المعلومات حول العمل مع السلاسل، تحقق من مقدمة للعمل مع السلاسل في Go.

سلاسل حروف بأحرف UTF-8

UTF-8 هو نظام ترميز يستخدم لترميز الأحرف بعرض متغير إلى بايت واحد إلى أربعة بايت. يدعم Go أحرف UTF-8 بشكل جاهز، دون الحاجة إلى أي إعداد خاص أو مكتبات أو حزم. الأحرف الرومانية مثل الحرف A يمكن تمثيلها بقيمة ASCII مثل الرقم 65. ومع ذلك، مع الأحرف الخاصة مثل الحرف الدولي ، سيكون مطلوبًا استخدام UTF-8. يستخدم Go نوع الألياف rune كاسم مستعار لبيانات UTF-8.

a := "Hello, 世界"

يمكنك استخدام كلمة السياق range في حلقة for للتنقل عبر أي سلسلة في Go، حتى سلسلة UTF-8. سيتم تناول حلقات for وكلمة السياق range بمزيد من التفصيل لاحقًا في السلسلة؛ في الوقت الحالي، من المهم معرفة أننا يمكن أن نستخدم هذا لحساب عدد البايتات في سلسلة معينة:

package main

import "fmt"

func main() {
	a := "Hello, 世界"
	for i, c := range a {
		fmt.Printf("%d: %s\n", i, string(c))
	}
	fmt.Println("length of 'Hello, 世界': ", len(a))
}

في الكتلة البرمجية أعلاه، أعلنا عن المتغير a وقمنا بتعيين القيمة Hello, 世界 له. النص المعين يحتوي على أحرف UTF-8 فيه.

ثم استخدمنا حلقة for قياسية وكذلك كلمة السياق range. في Go، ستقوم كلمة السياق range بالتنقل عبر سلسلة ما، مع إرجاع حرف واحد في كل مرة، بالإضافة إلى فهرس البايت الذي يوجد عنده الحرف في السلسلة.

باستخدام الدالة fmt.Printf، قدمنا سلسلة تنسيق من %d: %s\n. %d هو محرك الطباعة لرقم (في هذه الحالة عدد صحيح)، و%s هو محرك الطباعة لسلسلة. ثم قدمنا قيم i، التي تمثل الفهرس الحالي لحلقة for، وc، التي تمثل الحرف الحالي في حلقة for.

أخيرًا، طبعنا الطول الكامل للمتغير a باستخدام الدالة المدمجة len.

في وقت سابق، ذكرنا أن الحرف (rune) هو اسم مستعار لـ int32 ويمكن أن يتكون من بايت واحد إلى أربعة بايت. الحرف يأخذ ثلاثة بايت للتعريف ويتحرك الفهرس وفقًا لذلك عندما يتم تجاوز سلسلة UTF-8. هذا هو السبب في أن i ليس تسلسليًا عندما يتم طباعته.

Output
0: H 1: e 2: l 3: l 4: o 5: , 6: 7: 世 10: 界 length of 'Hello, 世界': 13

كما ترى، الطول أطول من عدد المرات التي استغرقتها للتجاوز على السلسلة.

لن تعمل دائمًا مع سلاسل UTF-8، ولكن عندما تفعل، ستفهم الآن سبب أنها حروف (runes) وليست int32 واحدة.

تعريف أنواع البيانات للمتغيرات

الآن بعد أن عرفت عن الأنواع البدائية المختلفة، سنتناول كيفية تعيين هذه الأنواع للمتغيرات في Go.

في Go، يمكننا تعريف متغير باستخدام الكلمة المفتاحية var متبوعة باسم المتغير ونوع البيانات المطلوب.

في المثال التالي سنعلن عن متغير يسمى pi من نوع float64.

الكلمة المفتاحية var هي أول شيء يتم الإعلان عنه:

var pi float64

تليها اسم متغيرنا، pi:

var pi float64

وأخيرًا نوع البيانات float64:

var pi float64

يمكننا أيضًا تحديد قيمة أولية اختيارية، مثل 3.14:

var pi float64 = 3.14

Go هي لغة مكتبة ساكنة. المكتبة الساكنة تعني أن كل عبارة في البرنامج يتم فحصها في وقت التصنيع. كما أنها تعني أن نوع البيانات مرتبط بالمتغير، بينما في اللغات الديناميكية المرتبطة، نوع البيانات مرتبط بالقيمة.

على سبيل المثال، في Go، يتم الإعلان عن النوع عند الإعلان عن متغير:

var pi float64 = 3.14
var week int = 7

كل من هذه المتغيرات يمكن أن تكون من نوع بيانات مختلف إذا تم الإعلان عنها بشكل مختلف.

هذا يختلف عن لغة مثل PHP، حيث يرتبط نوع البيانات بالقيمة:

$s = "sammy";         // $s تصبح تلقائيًا سلسلة
$s = 123;             // $s تصبح تلقائيًا عدد صحيح

في الكتلة البرمجية السابقة، الأولى $s هي سلسلة لأنها معينة القيمة "sammy"، والثانية هي عدد صحيح لأن لها القيمة 123.

التالي، دعونا ننظر إلى أنواع البيانات الأكثر تعقيدًا مثل المصفوفات.

المصفوفات

مصفوفة هي تسلسل مرتب من العناصر. تحدد سعة المصفوفة في وقت الإنشاء. بمجرد تخصيص المصفوفة لحجمها، لا يمكن تغيير الحجم بعد الآن. نظرًا لأن حجم المصفوفة ثابت، فهذا يعني أنها تخصص الذاكرة مرة واحدة فقط. هذا يجعل المصفوفات صعبة التعامل معها بعض الشيء، لكنه يزيد من أداء برنامجك. ولهذا السبب، تُستخدم المصفوفات عادةً عند تحسين البرامج. الشرائح، التي سنتناولها بعد ذلك، أكثر مرونة، وتشكل ما تعتقده بأنها مصفوفات في لغات أخرى.

تُعرف المصفوفات بتعريف حجم المصفوفة، ثم نوع البيانات مع تعريف القيم بين الأقواس المعقوفة { }.

مثال على مصفوفة من السلاسل النصية يبدو كالتالي:

[3]string{"blue coral", "staghorn coral", "pillar coral"}

يمكننا تخزين مصفوفة في متغير وطباعتها:

coral := [3]string{"blue coral", "staghorn coral", "pillar coral"}
fmt.Println(coral)
Output
[blue coral staghorn coral pillar coral]

كما ذكرنا سابقًا، الشرائح تشبه المصفوفات، لكنها أكثر مرونة بكثير. دعونا نلقي نظرة على نوع البيانات هذا الذي يمكن تغييره.

الشرائح

شريحة هي تسلسل مرتب من العناصر يمكن أن يتغير طوله. يمكن للشرائح زيادة حجمها ديناميكيًا. عند إضافة عناصر جديدة إلى شريحة، إذا لم تكن الشريحة لديها ذاكرة كافية لتخزين العناصر الجديدة، فسوف تطلب المزيد من الذاكرة من النظام حسب الحاجة. نظرًا لأن الشريحة يمكن توسيعها لإضافة المزيد من العناصر عند الحاجة، فإنها تُستخدم بشكل أكثر شيوعًا من المصفوفات.

تم تعريف الأجزاء بعناية بعد إعلان النوع المفرد وإغلاقه باستخدام أقليمين علامين من الزاوية للبدء [] وتحتوي على قيم بين أقليمين أولياء { } .

تبدو قطعة من الأعداد كما يلي:

[]int{-3, -2, -1, 0, 1, 2, 3}

تبدو قطعة من الأرقام المنخفضة كما يلي:

[]float64{3.14, 9.23, 111.11, 312.12, 1.05}

تبدو قطعة من الأكسر النصية كما يلي:

[]string{"shark", "cuttlefish", "squid", "mantis shrimp"}

دعونا نحدد قطعة من الأكسر النصية بـ seaCreatures:

seaCreatures := []string{"shark", "cuttlefish", "squid", "mantis shrimp"}

يمكننا طباعتها بمهمة المتغير:

fmt.Println(seaCreatures)

ستبدو الناتج بالضبط مثل القائمة التي أنشأناه:

Output
[shark cuttlefish squid mantis shrimp]

يمكننا استخدام كلمة السياسة append لإضافة عنصر لقطعتنا. الأمر التالي سيأخذ قيمة قطعة النص seahorse إلى القطعة:

seaCreatures = append(seaCreatures, "seahorse")

يمكنك تحقيقها بطباعتها:

fmt.Println(seaCreatures)
Output
[shark cuttlefish squid mantis shrimp seahorse]

كما ترون, إذا كان عليك إدارة حجم غير معروف للعناصر, فإن القطعة ستكون أكثر قابلية للاستخدام من التواريخ.

الخرائط

map هو نوع الـGo من المجموعة المفردة أو ما يسمى بالدليل. يستخدم الخرائط المفاتيح و قيم المفاتيح لتخزين البيانات. هذا مفيد في البرمجة للبحث بسرعة عن القيم بواسطة معرفيها, أو في هذه الحالة, معرفيها. على سبيل المثال, قد ترغب في إبقاء خريطة للمستخدمين, مرتبطة بمعرفيهم المستخدمين. المفتاح سيكون معرفي المستخدم, وكيان المستخدم البيانات

map[key]value{}

تُستخدم عادة لحفظ البيانات المتعلقة، مثل المعلومات الموجودة في معرف، تبدو الخريطة هكذا:

map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"}

ستلاحظ أنه بالإضافة إلى الأقواس المتعرجة، هناك أيضًا النقاط المزدوجة في جميع أنحاء الخريطة. الكلمات على يسار النقاط المزدوجة هي المفاتيح. يمكن أن تكون المفاتيح أي نوع قابل للمقارنة في Go. الأنواع القابلة للمقارنة هي أنواع بدائية مثل strings، ints، إلخ. النوع البدائي معرف بواسطة اللغة ولا يتم بناؤه من خلال دمج أي أنواع أخرى. بينما يمكن أن تكون من أنواع معرفة من قبل المستخدم، يعتبر من الأفضل ممارسة الاحتفاظ بها بسيطة لتجنب أخطاء البرمجة. المفاتيح في القاموس أعلاه هي: name، animal، color، و location.

الكلمات على يمين النقاط المزدوجة هي القيم. يمكن أن تتكون القيم من أي نوع بيانات. القيم في القاموس أعلاه هي: Sammy، shark، blue، و ocean.

دعونا نخزن الخريطة داخل متغير ونطبعها:

sammy := map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"}
fmt.Println(sammy)
Output
map[animal:shark color:blue location:ocean name:Sammy]

إذا أردنا عزل لون سامي، يمكننا القيام بذلك عن طريق استدعاء sammy["color"]. لنطبع ذلك:

fmt.Println(sammy["color"])
Output
blue

كما تقدم الخرائط أزواج مفاتيح-قيم لتخزين البيانات، يمكن أن تكون عناصر مهمة في برنامج Go الخاص بك.

الخاتمة

في هذه المرحلة، يجب أن يكون لديك فهم أفضل لبعض أنواع البيانات الرئيسية المتاحة لك للاستخدام في Go. سيصبح كل من هذه أنواع البيانات مهمًا مع تطويرك لمشاريع البرمجة بلغة Go.

بمجرد أن تكتسب فهمًا جيدًا لأنواع البيانات المتاحة لك في Go، يمكنك تعلم كيفية تحويل أنواع البيانات من أجل تغيير أنواع البيانات وفقًا للحالة.

Source:
https://www.digitalocean.com/community/tutorials/understanding-data-types-in-go