الأساسيات

الحلقات Loops

تستخدم الحلقات loops في لغة غو (ولغات اخرى) لتنفيذ أكواد معينة بشكل متكرر

في لغة غو يوجد فقط حلقات من نوع for, ولكن لايوجد حلقات من نوع while ولا do while.

صيغة حلقات for

for initialisation; condition; post {
}

وهو نفس الشكل القياسي لحلقات for في اغلب لغات البرمجة, حيث في البداية نكتب الكلمة المفتاحية for ومن ثم نضع متغير ابتدائي (مثل i) وثم نضع الشرط الذي يجب ان يتحقق لكي تتم كل دورة ومن ثم نضع تصريح ما
ليتم تنفيذه عند نهاية كل دورة (مثل i++)

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

مثال

import (
	"fmt"
)

func main() {
	for i := 1; 10 >= i; i++ {
		fmt.Println(i)
	}
}

وكما تلاحظ أن هذه حلقة for بسيطة مهمتها طباعة الأعداد 1 إلى 10

  • إيقاف الحلقة والخروج منها (استخدام المكابح!) break

يمكننا استخدام المكابح في حلقات for اذا اردنا إيقاف عمل الحلقة والخروج منها (عند تحقق شرط ما مثلاً)
وفي هذه الحالة سيتم الخروج من الحلقة حتى لو كان الشرط الرئيسي الموجود في جملة الحلقة for; محقق

مثال

package main

import (
	"fmt"
)

func main() {

	for i := 1; 10 >= i; i++ { 
if i > 5 {
			break
		}
		fmt.Println(i)
	}

	fmt.Println("now we're outside the for loop")
}

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

1
2
3
4
5
now we're outside the for loop

كما لاحظت فإن الشرط الرئيسي في جملة الحلقة هو تعداد الارقام من 1 حتى 10
ولكن داخل الحلقة كتبنا شرط آخر يتحقق فيما إذا وصلنا للرقم 5, إذاً, أوقف الحلقة واخرج منها
وخارج الحلقة (ضمن الدالة main) قمنا بأمر كتابة جملة now we’re outside the for loop

  • تخطي بعض الدورات continue

    نلاحظ انه عند استخدام المكابح, يتم إيقاف الحلقة كلياً والخروج منها
    لكن ماذا لو أردنا فقط أن نتخطى بعض الدورات Iterations دون الخروج من الحلقة أو إيقافها؟ عندها نستخدم continue

مثال

package main

import (
	"fmt"
)

func main() {
	for i := 1; 10 >= i; i++ {
		if i%2 == 0 {
			continue
		}
		fmt.Println(i)
	}
}

النتيجة

1
3
5
7
9

في المثال السابق, كتبنا جملة حلقة for تطبع لنا الأعداد من 1 حتى 10
ولكن داخل أكواد الحلقة وضعنا شرط للتحقق اذا كان رقم الدورة الحالية زوجي أو فردي
فإذا كان رقم الدورة الحالية هو عدد زوجي فسيتم تنفيذ continue وسيتم تخطي هذه الدورة والانتقال مباشرة الى الدورة التالية دون تنفيذ باقي الاكواد
أما اذا كان رقم الدورة الحالية هو عدد فردي فسيتم طباعته.

 

مثال

package main

import (  
    "fmt"
)

func main() {  
    n := 5
    for i := 0; n > i; i++ {
        for j := 0; i >= j; j++ {
            fmt.Print("*")
        }
        fmt.Println()
    }
}

والنتيجة

*
**
***
****
*****
  • إيقاف الحلقات الخارجية من الحلقات الداخلية, الملصقات Labels

    تٌستخدم الملصقات أو Labels عندما يكون لدينا حلقات for متداخلة ونريد أن نوقف عمل الحلقة الخارجية من خلال تعليمات في الحلقة الداخلية كما سنرى في الامثلة التالية

لنفرض انه لدينا الحلقة التالية

package main

import (  
    "fmt"
)

func main() {  
    for i := 0; 3 > i; i++ {
        for j := 1; 4 > j; j++ {
            fmt.Printf("i = %d , j = %d\n", i, j)
        }

    }
}

وهي حلقة عادية تعطينا النتيجة التالية

i = 0 , j = 1  
i = 0 , j = 2  
i = 0 , j = 3  
i = 1 , j = 1  
i = 1 , j = 2  
i = 1 , j = 3  
i = 2 , j = 1  
i = 2 , j = 2  
i = 2 , j = 3

ولكن ماذا لو أردنا أن نتوقف عن الطباعة عندما يكون المتغيران i و j متساويان ؟
لفعل ذلك نستخدم المكابح break للحلقة الخارجية.
ولكن استخدام المكابح في الحلقة الداخلية عندما يكونان المتغيران متساويان فقط سيوقف عمل الحلقة الداخلية

package main

import (  
    "fmt"
)

func main() {  
    for i := 0; 3 > i; i++ {
        for j := 1; 4 > j; j++ {
            fmt.Printf("i = %d , j = %d\n", i, j)
            if i == j {
                break
            }
        }

    }
}

والنتيجة

i = 0 , j = 1  
i = 0 , j = 2  
i = 0 , j = 3  
i = 1 , j = 1  
i = 2 , j = 1 
i = 2 , j = 2

ولكن هذه ليست النتيجة التي نريدها, نحن نريد ان نوقف عمل الحلقات عندما يكونان i و j متساويان (كما في السطر الرابع من النتيجة السابقة)
وهنا تأتي فعالية الملصقات Labels !

مثال

package main

import (  
    "fmt"
)

func main() {  
outer:  
    for i := 0; 3 > i; i++ {
        for j := 1; 4 > j; j++ {
            fmt.Printf("i = %d , j = %d\n", i, j)
            if i == j {
                break outer
            }
        }

    }
}

في السطر الثامن قمنا بوضع ملصق Label باسم outer قبيل جملة الحلقة الخارجية, أي عندما نذكر outer فنحن نقصد الحلقة الموجودة في السطر التاسع
وفي داخل الحلقة الداخلية وضعنا شرط اذا كان المتغيران i و j متساويان, استخدم المكابح break للحلقة الخارجية outer

والنتيجة

i = 0 , j = 1  
i = 0 , j = 2  
i = 0 , j = 3  
i = 1 , j = 1
  • امثلة اخرى

مثال 1

package main

import (  
    "fmt"
)

func main() {  
    i := 0
    for 10 >= i {
        fmt.Printf("%d ", i)
        i += 2
    }
}

مثال 2

package main

import (  
    "fmt"
)

func main() {  
    for no, i := 10, 1; 10 >= i && 19 >= no; i, no = i+1, no+1 {
        fmt.Printf("%d * %d = %d\n", no, i, no*i)
    }

}

مثال 3 ( حلقة لانهائية infinite loop)

package main

import "fmt"

func main() {  
    for {
        fmt.Println("Hello World")
    }
}
ملاحظة: يمكنك تشغيل أكواد وأمثلة لغة غو من خلال GoLang Playground أو GoPlay.Space .

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

Firas M. Darwish

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

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