1.9.1 حلقه #
حلقهها را در زبان گو به سادهترین شکل ممکن و فقط با استفاده از کلید واژه for و در مدلهای مختلف (سهبخشی, بی نهایت, foreach و …) میتوان پیادهسازی کرد.
1.9.2 حلقه سه بخشی #
این نمونه که متداولترین نوع حلقه for
نیز هستند با استفاده از سهبخش:
- مقداردهی
- شرط
- شمارنده
ایجاد میشوند.
در مثال زیر نمونهای از این حلقه قابل مشاهده و اجرا است.
1package main
2
3import "fmt"
4
5func main() {
6 sum := 0
7 for i := 1; i < 10; i++ {
8 sum += i
9 }
10
11 fmt.Println(sum)
12}
1.9.3 حلقه while #
این مدل حلقه تماماً شبیه به رفتار while در زبان C را دارد با این تفاوت که پیادهسازی آن، تنها با کلیدواژهی for
و با حذف بخش مقداردهی و شمارنده حلقه سهبخشی انجام میگیرد. در واقع در این حلقه تنها یک شرط تعریف میشود و تا برقرار بودن آن شرط حلقه اجرا میشود. به مثال زیر توجه کنید:
1package main
2
3import "fmt"
4
5func main() {
6 i := 0
7 for i < 10 {
8 fmt.Println(i)
9 i++
10 }
11}
1.9.4 حلقه بینهایت #
اگر از حلقهی while
که در مثال بالا تعریف کردیم بخش شرط را حذف کنیم چه اتفاقی میافتد؟ در این حالت ما یک شرط بی نهایت ساختهایم (شبیه به while(1)) که تا زمانی که برنامه متوقف نشود و یا کدهای داخل حلقه، فرمان خروج از حلقه را ندهند، چرخه ی اجرای حلقه ادامه خواهد یافت.
1package main
2
3import "fmt"
4
5func main() {
6 sum := 0
7 for {
8 sum++
9 }
10
11 fmt.Println("this line will never execute")
12}
با اجرای کد بالا خطای تایماوت دریافت خواهید کرد (اگر در playground سایت گو اجراش کنین)
، بهدلیل اینکه حلقه هیچگاه تمام نمیشود.
1.9.5 حلقه for-range #
حلقه for-range یکی از پرکاربردترین حلقه ها در زبان گو می باشد که شما می توانید برای slice, آرایه و map یا رشته از این حلقه استفاده کنید.
1for index, value := range slice/array {}
1for key, value := range map {}
1.9.5.1 حلقه for-range برای slice و آرایه #
شما با استفاده از حلقه for-range می توانید به المنت های آرایه یا slice و همچنین اندیس شان (Index)
دسترسی پیدا کنید. دقت کنید ۲ حالت وجود دارد :
1.9.5.1.1 دسترسی با استفاده از یک کپی از المنت #
در کد زیر ما با استفاده از for-range به یک کپی از المنت های اسلایس letter
دسترسی پیدا کردیم.
1package main
2
3import "fmt"
4
5func main() {
6 letters := []string{"a", "b", "c"}
7
8 //With index and value
9 fmt.Println("Both Index and Value")
10 for i, letter := range letters {
11 fmt.Printf("Index: %d Value:%s\n", i, letter)
12 }
13
14 //Only value
15 fmt.Println("\nOnly value")
16 for _, letter := range letters {
17 fmt.Printf("Value: %s\n", letter)
18 }
19}
1$ go run main.go
2Both Index and Value
3Index: 0 Value:a
4Index: 1 Value:b
5Index: 2 Value:c
6
7Only value
8Value: a
9Value: b
10Value: c
1.9.5.1.2 دسترسی مستقیم به خانه حافظه المنت #
شما با استفاده از اندیس (index) می توانید مستقیما به خانه حافظه المنت دسترسی پیدا کنید و آن المنت رو با استفاده از اندیس (Index)
نمایش بدید. به مثال زیر توجه کنید :
1package main
2
3import "fmt"
4
5func main() {
6 letters := []string{"a", "b", "c"}
7
8 fmt.Println("\nOnly letter")
9 for i := range letters {
10 fmt.Printf("letter: %s\n", letters[i])
11 }
12}
1.9.1.2 حلقه for-range برای map #
شما با استفاده از حلقه for-range برروی map, میتوانید به کلید و مقدار هر یک از مقادیر map دسترسی پیدا کنید.
1package main
2
3import "fmt"
4
5func main() {
6 sample := map[string]string{
7 "a": "x",
8 "b": "y",
9 }
10
11 //Iterating over all keys and values
12 fmt.Println("Both Key and Value")
13 for k, v := range sample {
14 fmt.Printf("key :%s value: %s\n", k, v)
15 }
16
17 //Iterating over only keys
18 fmt.Println("\nOnly keys")
19 for k := range sample {
20 fmt.Printf("key :%s\n", k)
21 }
22
23 //Iterating over only values
24 fmt.Println("\nOnly values")
25 for _, v := range sample {
26 fmt.Printf("value :%s\n", v)
27 }
28}
1$go run main.go
2Both Key and Value
3key :a value: x
4key :b value: y
5
6Only keys
7key :a
8key :b
9
10Only values
11value :x
12value :y
1.9.1.3 حلقه for-range برای رشته (string) #
شما با استفاده از حلقه for-range می توانید به هرکدام از کارکترهای رشته دسترسی پیدا کنید.
به کد نمونه زیر توجه کنید :
1package main
2
3import "fmt"
4
5func main() {
6 sample := "a£b"
7
8 //With index and value
9 fmt.Println("Both Index and Value")
10 for i, letter := range sample {
11 fmt.Printf("Start Index: %d Value:%s\n", i, string(letter))
12 }
13
14 //Only value
15 fmt.Println("\nOnly value")
16 for _, letter := range sample {
17 fmt.Printf("Value:%s\n", string(letter))
18 }
19
20 //Only index
21 fmt.Println("\nOnly Index")
22 for i := range sample {
23 fmt.Printf("Start Index: %d\n", i)
24 }
25}
1$ go run main.go
2Both Index and Value
3Start Index: 0 Value:a
4Start Index: 1 Value:£
5Start Index: 3 Value:b
6
7Only value
8Value:a
9Value:£
10Value:b
11
12Only Index
13Start Index: 0
14Start Index: 1
15Start Index: 3
1.9.6 کلید واژه break #
با استفاده از break
میتوان چرخهی اجرای یک حلقه را پایان داد. به عنوان مثال در حلقه بینهایتی که در بخش 1.9.4
مشاهده کردید, میتوان با تعریف یک شرط خاص از حلقه خارج شد. کد زیر نمونه استفاده از break
را نمایش میدهد.
1package main
2
3import "fmt"
4
5func main() {
6 sum := 0
7 for {
8 sum++
9 if sum == 10 {
10 break
11 }
12 }
13
14 fmt.Println(sum)
15 fmt.Println("now this line will execute")
16}
1.9.7 کلیدواژه continue #
این کلیدواژه چرخهی اجرای حلقه را یک مرحله جلو میبرد. به اینمعنی که اگر در حلقه از این کلیدواژه استفاده شود، کدهای بعد از continue اجرا نشده و چرخه بعدی (گام بعدی) اجرا خواهد شد.
1package main
2
3import "fmt"
4
5func main() {
6
7 for i := 1; i < 10; i++ {
8 if i%2 == 0 {
9 continue
10 }
11 fmt.Println(i)
12 }
13}
قابل ذکر است کهcontinue
وbreak
در حلقههای تودرتو، فقط روی اولین حلقه درونی تاثیر خواهند گذاشت.
1.9.8 خودآزمون حلقه #
با استفاده از زبان Go برنامهای بنویسید که سری زیر را ایجاد کند:
- 1 + 0 = 1
- 1 + 1 = 2
- 2 + 1 = 3
- 3 + 2 = 5
- 5 + 3 = 8
- 8 + 5 = 13
- 13 + 8 = 21
- a + b = c
- b = a
- a = c