1 مقدمة إلى أنواع البيانات في لغة Go
في لغة Go، تعتبر أنواع البيانات أساس البرمجة، حيث تحدد شكل البيانات التي يمكن للمتغيرات تخزينها. يتم تقسيم أنواع البيانات الأساسية التي تقدمها لغة Go بشكل رئيسي إلى الفئات التالية:
نوع البيانات | الوصف | استخدام الذاكرة |
---|---|---|
bool | نوع بولياني، يُستخدم لتخزين قيم صح أو خطأ | 1 بايت |
int، uint | أعداد صحيحة موقعة وغير موقعة، الحجم الافتراضي يعتمد على منصة النظام | 4 أو 8 بايت |
int8, uint8 | أعداد صحيحة موقعة وغير موقعة ب 8 بت | 1 بايت |
int16, uint16 | أعداد صحيحة موقعة وغير موقعة ب 16 بت | 2 بايت |
int32, uint32 | أعداد صحيحة موقعة وغير موقعة ب 32 بت | 4 بايت |
int64, uint64 | أعداد صحيحة موقعة وغير موقعة ب 64 بت | 8 بايت |
float32 | عدد عائم ب 32 بت | 4 بايت |
float64 | عدد عائم ب 64 بت | 8 بايت |
complex64 | عدد مركب مع أجزاء حقيقية ووهمية ب 32 بت | 8 بايت |
complex128 | عدد مركب مع أجزاء حقيقية ووهمية ب 64 بت | 16 بايت |
byte | مشابه ل uint8 | 1 بايت |
rune | مشابه ل int32، يمثل نقطة رمز يونيكود | 4 بايت |
string | نوع السلسلة | يعتمد على طول السلسلة |
error | واجهة الخطأ، تُستخدم لإرجاع معلومات الخطأ | لا يوجد حجم ثابت |
يمكن اختيار هذه الأنواع وفقًا للاحتياجات المختلفة، مثل الحسابات العددية، معالجة النصوص، أو التحكم المنطقي.
2 أنواع بيانات الأعداد الصحيحة
2.1 نظرة عامة على أنواع الأعداد الصحيحة
تحتوي لغة Go على العديد من أنواع الأعداد الصحيحة المدمجة، مصنّفة على النحو التالي:
- أعداد صحيحة موقعة:
int8
،int16
،int32
(أوrune
)،int64
، وint
- أعداد صحيحة غير موقعة:
uint8
(أوbyte
)،uint16
،uint32
،uint64
، وuint
حيث يكون حجم int
و uint
هو 4 بايت على أنظمة 32 بت و 8 بايت على أنظمة 64 بت. تُظهر الجدول أدناه نطاقات القيم لأنواع بيانات الأعداد الصحيحة:
النوع | نطاق القيم |
---|---|
int8 | -128 إلى 127 |
uint8 | 0 إلى 255 |
int16 | -32768 إلى 32767 |
uint16 | 0 إلى 65535 |
int32 | -2147483648 إلى 2147483647 |
uint32 | 0 إلى 4294967295 |
int64 | -9223372036854775808 إلى 9223372036854775807 |
uint64 | 0 إلى 18446744073709551615 |
2.2 استخدام متغيرات الأعداد الصحيحة
يكون الصيغة الأساسية لتعريف متغير عدد صحيح كما يلي:
var اسم_المتغير نوع_البيانات = القيمة_الأولية
على سبيل المثال:
package main
import "fmt"
func main() {
var a int = 10 // متغير عدد صحيح موقع
var b uint = 20 // متغير عدد صحيح غير موقع
var c int8 = -128 // أصغر قيمة int8
fmt.Println(a, b, c)
}
2.3 عمليات الأعداد الصحيحة
تدعم لغة Go العمليات الحسابية الشائعة، مثل الجمع (+
)، الطرح (-
)، الضرب (*
)، القسمة (/
)، والباقي (%
)، بالإضافة إلى العوامل البتية مثل العمليات البتية "و" (&
)، "أو" (|
)، "أكس أو" (^
)، التحويل البتي لليمين (<<
)، والتحويل البتي لليسار (>>
).
package main
import "fmt"
func main() {
x := 10
y := 3
// العمليات الحسابية
fmt.Println(x + y) // الجمع
fmt.Println(x - y) // الطرح
fmt.Println(x * y) // الضرب
fmt.Println(x / y) // القسمة
fmt.Println(x % y) // الباقي
// عمليات البت
fmt.Println(x & y) // العملية البتية "و"
fmt.Println(x | y) // العملية البتية "أو"
fmt.Println(x ^ y) // العملية البتية "أكس أو"
fmt.Println(x << 1) // تحويل بتي لليسار بمقدار 1
fmt.Println(x >> 1) // تحويل بتي لليمين بمقدار 1
}
3 أنواع بيانات الأعداد العائمة
3.1 نظرة عامة على أنواع البيانات العائمة
في لغة Go ، تشمل أنواع الأعداد العائمة float32
و float64
، والتي تعتبر تمثيلًا للبيانات العائمة بتنسيق 32 بت و 64 بت. بشكل عام ، يُوصى باستخدام float64
لأنه يوفر نطاقًا أوسع ودقة أكبر.
- يحتوي
float32
على حوالي 23 بت مهمة ، مما يوفر حوالي 7 أرقام عشرية من الدقة. - يحتوي
float64
على حوالي 52 بت مهمة ، مما يوفر حوالي 16 رقمًا عشريًا من الدقة.
3.2 استخدام المتغيرات العائمة
يمكن تعريف المتغيرات العائمة عن طريق توفير القيم الأساسية مباشرة أو باستخدام كلمة المفتاح var
:
package main
import "fmt"
func main() {
var f1 float32 = 3.14 // تحديد نوع float32 بشكل صريح
f2 := 3.14 // تم افتراضه تلقائيًا كنوع float64
fmt.Println(f1, f2)
}
3.3 العمليات الحسابية للأعداد العائمة والمشكلات
قد تؤدي عمليات الحساب للأعداد العائمة إلى فقدان الدقة. أداء العمليات بدقة عالية هو مشكلة شائعة ، خاصةً عند طرح رقمين قريبين جدًا.
package main
import "fmt"
func main() {
f1 := .1
f2 := .2
f3 := f1 + f2
fmt.Println(f3) // قد لا يكون الإخراج المتوقع هو .3 بسبب مشكلات الدقة
// إصلاح مشكلات الدقة باستخدام الإخراج المهيأ
fmt.Printf("%.1f\n", f3) // الإخراج المصحح إلى .3
}
4 نوع بيانات البوليان
4.1 نظرة عامة على نوع البيانات البولياني
البوليان هو أبسط نوع بيانات ، ويمكن أن يأخذ فقط قيمتين: true
(صحيح) و false
(خاطئ). إنه يحتل مكانة مهمة جدًا في التعبيرات الشرطية وهياكل التحكم في الحلقات.
4.2 استخدام المتغيرات البوليانية
تعريف واستخدام المتغيرات البوليانية:
package main
import "fmt"
func main() {
var success bool = true
var fail bool = false
fmt.Println("Operation successful:", success)
fmt.Println("Operation failed:", fail)
}
غالبًا ما يتم استخدام القيم البوليانية في التعبيرات الشرطية:
package main
import "fmt"
func main() {
a := 10
b := 20
fmt.Println("a == b:", a == b) // false
fmt.Println("a < b:", a < b) // true
}
5 نوع بيانات السلسلة
5.1 نظرة عامة على السلاسل
السلسلة هي مجموعة من الأحرف. في لغة Go ، السلاسل غير قابلة للتغيير. تتكون كل سلسلة من جزءين: مؤشر إلى صفيف البايتات الأساسي وطول. يمكن أن تحتوي السلاسل على أي بيانات بما في ذلك البايتات.
5.2 استخدام المتغيرات السلسلة
غالبًا ما يتم تعريف المتغيرات السلسلة باستخدام علامات اقتباس مزدوجة "
للإنشاء ، ولكن يمكنك أيضًا استخدام علامات اقتباس عكسية ` لإنشاء سلاسل على عدة أسطر:
package main
import "fmt"
func main() {
var s1 string = "hello"
s2 := "world"
s3 := `This is a
multiple line
string`
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(s3)
}
بمجرد إنشاء سلسلة ، لا يمكن تغيير محتواها. العملية التالية غير قانونية وستؤدي إلى خطأ في الترجمة:
s := "hello"
s[] = 'H` // خطأ في الترجمة: المحتوى الخاص بالسلسلة لا يمكن تغييره
5.3 العمليات على السلاسل
السلاسل شائعة ومهمة جدًا في البرمجة. توفر لغة Go مجموعة غنية من الدوال المدمجة للتلاعب بالسلاسل. فيما يلي بعض العمليات المستخدمة بشكل شائع.
5.3.1 اقتران السلاسل
في لغة Go ، يمكنك استخدام عامل الجمع (+
) لاقتران السلاسل ، وهو الطريقة الأكثر مباشرة. بالإضافة إلى ذلك ، عند التعامل مع اقتران متكرر لعدة سلاسل ، من المُوصَى باستخدام strings.Builder
للحصول على أداءٍ أفضل.
package main
import (
"fmt"
"strings"
)
func main() {
// اقتران السلاسل باستخدام الإضافة
hello := "Hello, "
world := "World!"
result := hello + world
fmt.Println(result) // الإخراج: Hello, World!
// اقتران السلاسل باستخدام strings.Builder
var sb strings.Builder
sb.WriteString("Hello, ")
sb.WriteString("World!")
fmt.Println(sb.String()) // الإخراج: Hello, World!
}
5.3.2 تقسيم السلاسل النصية
يمكن تقسيم السلاسل النصية باستخدام دالة strings.Split
، الّتي تقسم النص إلى قطع بناءً على الفاصل المحدد.
package main
import (
"fmt"
"strings"
)
func main() {
// تعريف نص
sentence := "Go هي لغة برمجة مفتوحة المصدر"
// تقسيم النص بواسطة المسافة
words := strings.Split(sentence, " ")
for _, word := range words {
fmt.Printf("%s\n", word)
}
// الناتج:
// Go
// هي
// لغة
// برمجة
// مفتوحة
// المصدر
}
5.3.3 الوصول بالفهرس
في Go، السلسلة النصية هي تسلسل لا يمكن تغييره من البايتات. يمكنك استخدام الفهرسة للوصول إلى بايتات محددة في سلسلة. ومع ذلك، من المهم ملاحظة أنه نظرًا لأن السلسلة قد تحتوي على أحرف متعددة البايتات (مثل الأحرف المشفرة بترميز UTF-8)، فإن الفهرسة المباشرة قد لا تعيد الحرف الواحد المتوقع.
package main
import "fmt"
func main() {
s := "Hello, 世界"
for i := 0; i < len(s); i++ {
fmt.Printf("%d: %x\n", i, s[i])
}
// ملاحظة: سيتم طباعة التمثيل الست عشري للبايتات، وليس الأحرف
}
للتكرار عبر السلسلة حسب الحرف، يمكنك استخدام الحلقة range
.
package main
import "fmt"
func main() {
s := "Hello, 世界"
for index, runeValue := range s {
fmt.Printf("%d: %U '%c'\n", index, runeValue, runeValue)
}
// الناتج: فهرس، الترميز اليونيكودي، والحرف نفسه لكل حرف
}
5.3.4 الحصول على الطول
يمكن لدالة len
الحصول على طول السلسلة، أي طول السلسلة البايتية الأساسية. بالنسبة للسلاسل UTF-8، إذا كنت بحاجة إلى الحصول على عدد الأحرف (runes)، يجب عليك استخدام دالة utf8.RuneCountInString
والتي تتعامل بشكل صحيح مع الأحرف متعددة البايتات.
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "Hello, 世界"
fmt.Println("طول البايتات:", len(s)) // المخرج: طول البايتات
fmt.Println("طول الأحرف:", utf8.RuneCountInString(s)) // المخرج: عدد الأحرف
}
من المثال أعلاه، يُظهر لنا لغة Go توفر وظائف غنية لعمليات معالجة السلاسل النصية، مما يجعل من السهل إنجاز مهام معالجة السلاسل المختلفة. عند البرمجة، من المهم الانتباه إلى التمييز بين البايتات والأحرف، خاصة عند التعامل مع مجموعات الأحرف غير ASCII.