1.11 حلقه ها (for)

1.11 حلقه ها (for)

1.11.1 حلقه #

حلقه‌ها را در زبان گو به ساده‌ترین شکل ممکن و فقط با استفاده از کلید واژه for و در مدل‌های مختلف (سه‌بخشی, بی نهایت, foreach و …) می‌توان پیاده‌سازی کرد.

1.11.2 حلقه سه بخشی #

این نمونه از حلقه‌ها که متداول‌ترین نوع حلقه است با استفاده از سه‌بخش:

  • مقداردهی
  • شرط
  • شمارنده

ایجاد می‌شوند.

1for initialization ; condition ; counter { 
2	//loop codes 
3} 

در کد زیر نمونه‌ای از این حلقه‌ها قابل مشاهده و اجرا است.

 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$ go run main.go
245

1.11.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$ go run main.go
 20
 31
 42
 53
 64
 75
 86
 97
108
119

1.11.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}

با اجرای کد بالا خطای تایم‌اوت دریافت خواهید کرد، به‌دلیل اینکه حلقه هیچگاه پایان نمی‌پذیرد.

1.11.5 حلقه for-range #

حلقه for-range یکی از پرکاربردترین حلقه ها در زبان گو می باشد که شما می توانید برای slice, آرایه و map یا رشته از این حلقه استفاده کنید.

1for index, value := range slice/array {}
1for key, value := range map {}

1.11.5.1 حلقه for-range برای slice و آرایه #

شما با استفاده از حلقه for-range می توانید به المنت های آرایه و slice و همچنین اندیس شان دسترسی پیدا کنید. و دقت کنید ۲ حالت وجود دارد :

1.11.5.1.1 دسترسی با استفاده از یک کپی از المنت #

در کد زیر ما با استفاده از for-range به یک کپی از المنت های slice 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.11.5.1.2 دسترسی مستقیم به خانه حافظه المنت #

شما با استفاده از اندیس (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$go run main.go
2Only letter
3letter: a
4letter: b
5letter: c

1.15.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.15.1.3 حلقه for-range برای رشته (string) #

شما با استفاده از حلقه for-range می توانید به هرکدام از کارکترهای رشته دسترسی پیدا کنید.

1for index, character := range string {
2    //Do something with index and character
3}

به کد نمونه زیر توجه کنید :

 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.11.6 کلید واژه break #

با استفاده از break می‌توان چرخه‌ی اجرای یک حلقه را پایان داد. به عنوان مثال در حلقه بی‌نهایت بالا می‌توان با تعریف یک شرط خاص از حلقه خارج شد. کد زیر نمونه استفاده از 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$ go run main.go
210
3now this line will execute

1.11.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}
1$ go run main.go
21
33
45
57
69
قابل ذکر است که continue و break در حلقه‌های تودرتو، فقط روی اولین حلقه درونی تاثیر خواهند گذاشت.

1.11.8 خودآزمون حلقه #

با استفاده از زبان Go برنامه‌ای بنویسید که سری‌ زیر را ایجاد کند:

11
222
3333
455555
588888888
613131313131313131313131313
7212121212121212121212121212121212121212121
  • ‍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

 1package main  
 2  
 3import "fmt"  
 4  
 5func main() {  
 6   var (  
 7      n       = 6  // can define any result count ...  
 8      a, b, c = 1, 0, 0  
 9   )  
10   for i := 0; i <= n; i++ {  
11      c = a + b  
12      for j := 1; j <= c; j++ {  
13         fmt.Print(c)  
14      }  
15      fmt.Println()  
16      b, a = a, c  
17   }  
18}
comments powered by Disqus