ورقة غش لغة البرمجة Go
Go (تُعرف أيضاً باسم Golang) هي لغة مجمعة وذات كتابة ثابتة تم تطويرها بواسطة Robert Griesemer و Rob Pike و Ken Thompson في Google. تشبه قواعد Go قواعد لغة C، ولكنها تتميز بـ: سلامة الذاكرة، و GC (جمع النفايات)، والنوع الهيكلي، وحساب التزامن بنمط CSP.
Hello world
package main
import "fmt"
func main() {
message := greetMe("world")
fmt.Println(message)
}
func greetMe(name string) (string) {
return "Hello, " + name + "!"
}
$ go buildالمتغيرات
إعلان المتغيرات
var msg string
msg = "Hello"الاختصار
msg := "Hello"الثوابت
const Phi = 1.618يمكن أن تكون الثوابت أحرفاً أو سلاسل نصية أو قيماً منطقية أو قيمًا رقمية.
الأنواع الأساسية
السلاسل النصية (Strings)
str := "Hello"
str := `سلسلة
متعددة الأسطر`نوع السلاسل النصية هو string.
الأرقام
الأنواع النموذجية
num := 3 // int
num := 3. // float64
num := 3 + 4i // complex128
num := byte('a') // byte (اسم مستعار لـ uint8)أنواع أخرى
var u uint = 7 // uint (بدون إشارة)
var p float32 = 22.7 // float 32-bitالمؤشرات (Pointers)
func main () {
b := *getPointer()
fmt.Println("القيمة هي", b)
}
func getPointer () (myPointer *int) {
a := 234
return &a
}تشير المؤشرات إلى موقع ذاكرة لمتغير. لغة Go مجهزة بالكامل بجمع النفايات (Garbage Collection).
المصفوفات (Arrays)
// var numbers [5]int
numbers := [...]int{0, 0, 0, 0, 0}حجم المصفوفات ثابت.
الشرائح (Slices)
slice := []int{2, 3, 4}
slice := []byte("Hello")على عكس المصفوفات، تتميز الشرائح بحجم ديناميكي.
التحكم في التدفق
الشروط
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}تعبير في if
if _, err := getResult(); err != nil {
fmt.Println("Uh oh")
}يمكن لعبارة if تنفيذ عبارة بسيطة قبل التعبير الشرطي.
Switch
switch day {
case "sunday":
// الحالات لا "تنفذ تباعاً" افتراضياً!
fallthrough
case "saturday":
rest()
default:
work()
}الدوال
Lambdas
myfunc := func() bool {
return x > 10000
}الدوال هي كائنات من الدرجة الأولى.
أنواع إرجاع متعددة
a, b := getMessage()
func getMessage() (a string, b string) {
return "Hello", "World"
}قيم الإرجاع المسماة
func split(sum int) (x, y int) {
x := sum * 4 / 9
y := sum - x
return
}من خلال تسمية قيم الإرجاع في التعريف، فإن return (بدون وسائط) ستعيد المتغيرات بتلك الأسماء.
الحزم (Packages)
التحميل
import "fmt"
import "math/rand"
import (
"fmt" // يعطي fmt.Println
"math/rand" // يعطي rand.Intn
)كلاهما متماثل.
الأسماء المستعارة
import r "math/rand"
r.Intn()الأسماء المصدرة
func Hello () {
···
}تبدأ الأسماء المصدرة بحرف كبير.
الحزم
package helloيجب أن يبدأ كل ملف حزمة بكلمة package.
التزامن (Concurrency)
Goroutines
func main() {
// قناة "channel"
ch := make(chan string)
// بدء إجراءات متزامنة
go push("Moe", ch)
go push("Larry", ch)
go push("Curly", ch)
// قراءة 3 نتائج
// (بما أن goroutines متزامنة،
// فالترتيب غير مضمون!)
fmt.Println(<-ch, <-ch, <-ch)
}
func push(name string, ch chan string) {
msg := "Hey, " + name
ch <- msg
}القنوات هي كائنات اتصال آمنة للتزامن تُستخدم في goroutines.
القنوات المخزنة (Buffered Channels)
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// خطأ فادح:
// كل الـ goroutines نائمة - طريق مسدود (deadlock)!تحد القنوات المخزنة من عدد الرسائل التي يمكنها الاحتفاظ بها.
إغلاق القنوات
يغلق القناة
ch <- 1
ch <- 2
ch <- 3
close(ch)التنقل عبر القناة حتى إغلاقها
for i := range ch {
···
}تعتبر مغلقة إذا كانت ok == false
v, ok := <- chالتأجيل والذعر (Defer & Panic)
Defer (التأجيل)
func main() {
defer fmt.Println("Done")
fmt.Println("Working...")
}يؤجل تنفيذ الدالة حتى تعود الدالة المحيطة. يتم تقييم الوسائط على الفور، ولكن لا يتم استدعاء الدالة حتى النهاية.
Defer مع Lambdas
func main() {
defer func() {
fmt.Println("Done")
}()
fmt.Println("Working...")
}تعتبر Lambdas أفضل للكتل المؤجلة.
الهياكل (Structs)
التعريف
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X, v.Y)
}الثوابت الحرفية
v := Vertex{X: 1, Y: 2}
// يمكن حذف أسماء الحقول
v := Vertex{1, 2}
// Y ضمني
v := Vertex{X: 1}يمكنك أيضًا تحديد أسماء الحقول.
المؤشرات إلى الهياكل
v := &Vertex{1, 2}
v.X = 2عندما يكون v مؤشراً، فإن v.X و (*v).X متماثلان.
الأساليب (Methods)
المستقبِل (Receivers)
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
v := Vertex{1, 2}
v.Abs()لا توجد أصناف، ولكن يمكنك تعريف دوال على الأنواع باستخدام المستقبلِلات.
مستقبِلات المؤشر
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
v := Vertex{6, 12}
v.Scale(0.5)
// يتم تحديث `v`